Как реализовать обработчики в Android из потока в отдельном файле - PullRequest
0 голосов
/ 16 декабря 2011

Мне было интересно, как использовать обработчик в Android для отправки двух сообщений из отдельного потока для обновления пользовательского интерфейса.Поток объявлен в другом файле.Я понимаю, что использование java Thread нежелательно в Android, но я отказался от использования методов Android, они ужасны.Сообщения обработчика отправляются каждые 200 миллисекунд из моего объявленного потока.Я не могу найти достойный пример того, как это реализовать.

Вот мой расширенный поток.Это вызвано из деятельности.

import java.io.IOException;

import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Message;

public class MPlayer extends Thread {
    private volatile boolean playing = false;
    private volatile boolean finished = false;
    MediaPlayer player;
    Message msg;
    Bundle bundle;
    String filepath;

    /* other fields, constructor etc. */
    public MPlayer(String path) {
        filepath = path;
        player = new MediaPlayer();
        bundle = new Bundle();
        msg = new Message();
        start();
    }

    public void seekMPlayer(int i) {
        // TODO Auto-generated method stub
        player.seekTo(i);
    }

    public boolean getPlaying() {
        // TODO Auto-generated method stub
        return playing;
    }

    @Override
    public void run() {
        try {
            player.setDataSource(filepath);
            player.prepare();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        while (!finished) {
            while (playing && !finished) {
                try {
                    Thread.sleep(200);
                    if (playing && !finished) {
                        bundle.putString("progval", songTime());
                        // msg.setData(bundle);
                        // threadHandler.sendMessage(msg);
                    } else
                        break;
                } catch (InterruptedException e) {

                }
            }
        }

    }

    public synchronized void pauseMPlayer() {
        playing = false;
        player.pause();

    }

    public synchronized void PlayMPlayer() {
        playing = true;
        player.start();
        // call notify() here when you switch to wait/notify.
    }

    public void stopMPlayer() {
        playing = false;
        finished = true;
        player.release();
        // call notify() here too.
    }

    private String songTime() {
        // TODO Auto-generated method stub
        if (filepath != null) {
            int progressseconds = (int) ((player.getCurrentPosition() / 1000) % 60);
            int progressminutes = (int) ((player.getCurrentPosition() / 1000) / 60);
            int durationseconds = (int) ((player.getDuration() / 1000) % 60);
            int durationminutes = (int) ((player.getDuration() / 1000) / 60);
            String progmin, progsec, durmin, dursec;
            if (progressminutes >= 10)
                progmin = Integer.toString(progressminutes);
            else
                progmin = "0" + Integer.toString(progressminutes);
            if (progressseconds >= 10)
                progsec = Integer.toString(progressseconds);
            else
                progsec = "0" + Integer.toString(progressseconds);
            if (durationminutes >= 10)
                durmin = Integer.toString(durationminutes);
            else
                durmin = "0" + Integer.toString(durationminutes);
            if (durationseconds >= 10)
                dursec = Integer.toString(durationseconds);
            else
                dursec = "0" + Integer.toString(durationseconds);
            return (progmin + ":" + progsec + "/" + durmin + ":" + dursec);
        } else {
            return ("No File!");
        }
    }
}

Ответы [ 2 ]

1 голос
/ 16 декабря 2011

Обработчик должен связать лупер потока. Используйте этот конструктор, чтобы указать петлитель потока

Handler handler = new Handler(Looper.getMainLooper());

А теперь вы можете отправить сообщение в основную ветку

0 голосов
/ 16 декабря 2011

Нет ничего плохого в том, чтобы использовать потоки Java в Android, но немного излишне использовать его только для отправки периодических сообщений. Рекомендуемый способ сделать это - использовать Handler.postDelayed . В этой статье предлагается следующий метод: поместите весь ваш код обновления в Runnable и добавьте postDelayed вызов в конец run() этого Runnable, чтобы запланировать его снова. Этот подход устраняет накладные расходы на наличие фонового потока.

Однако Handler легко использовать для отправки сообщений из другого потока. Как я понимаю, вы пытаетесь отправить сообщения на какой-либо компонент пользовательского интерфейса, чтобы он мог обновляться сам. В моем приложении я столкнулся с подобной проблемой. Я объявил обработчик внутри компонента пользовательского интерфейса и передал этот обработчик фоновому потоку в параметре конструктора.

Часть пользовательского интерфейса выглядит так:

class MyActivity extends Activity {
    Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            // update UI according to a content of msg from background thread
            // ...
        }
    };

    private Thread mBackgroundWorker = new BackgroundThread(mHandler);

    protected void onCreate(Bundle savedInstanceState) {
        // ...
        mBackgroundWorker.start();
        // ...
    }

    protected void onDestroy() {
        // we created the thread in this activity 
        // so we should manage its lifecycle here
        mBackgroundWorker.interrupt();
    }
}

А фоновый поток реализован как

class BackgroundThread extends Thread {

    private final mHandler;

    public BackgroundThread(Handler h) {
        mHandler = h;
    }


    public void run() {
        // do some processing...
        mHandler.sendMessage(/*some message to update an UI*/);
        // ...
    }
}
...