【问题标题】:How to implement handlers in Android from a thread in seperate file如何从单独文件中的线程在 Android 中实现处理程序
【发布时间】:2012-01-21 16:26:40
【问题描述】:

我想知道如何在 android 中使用处理程序从单独的线程发送两条消息以更新 UI。该线程在另一个文件中声明。我知道在 Android 中使用 java Thread 是不可取的,但我已经放弃使用 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!");
        }
    }
}

【问题讨论】:

    标签: android multithreading handler message


    【解决方案1】:

    在 Android 中使用 Java 线程没有任何问题,但仅将其用于发送定期消息有点过头了。推荐的方法是使用Handler.postDelayed。本文建议采用以下方法:将所有更新代码放入Runnable 并在此Runnable 的run() 末尾添加postDelayed 调用以重新安排它。这种方法消除了拥有后台线程的开销。

    但是,使用 Handler 从另一个线程发送消息很容易。据我了解,您正在尝试向某些 UI 组件发送消息,以便它可以自行更新。 在我的应用程序中,我遇到了类似的问题。我在 UI 组件中声明了一个处理程序,并在构造函数参数中将此处理程序传递给后台线程。

    UI 部分如下所示:

    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*/);
            // ...
        }
    }
    

    【讨论】:

      【解决方案2】:

      Handler 应该绑定一个 Looper 的线程。使用此构造函数指定线程循环器

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

      现在你可以向主线程发送消息

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-23
        • 1970-01-01
        相关资源
        最近更新 更多