如何在 Android 中从单独文件中的线程实现处理程序

发布于 2024-12-21 20:31:06 字数 3798 浏览 1 评论 0原文

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

I was wondering how to use a handler in android to send two messages from a separate thread to update UI. The thread is declared in another file. I understand that using java Thread is not desirable in Android, but I have given up using android methods, they are terrible. The handler messages are sent every 200 miliseconds from my declared thread. I cannot find a decent example of how to implement it.

Here is my extended thread. This is called from the activity.

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!");
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

殊姿 2024-12-28 20:31:06

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

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

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

Handler should bind a Looper of the thread. Use this constructor to specify a thread looper

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

And now the you can send message to the main thread

我喜欢麦丽素 2024-12-28 20:31:06

在 Android 中使用 Java 线程并没有什么问题,但是仅仅使用它来发送周期性消息就有点大材小用了。推荐的方法是使用 Handler.postDelayed。本文建议使用以下方法:将所有更新代码放入 Runnable 中,并将 postDelayed 调用添加到此 Runnable 的 run() 末尾以进行调度再来一次。这种方法消除了后台线程的开销。

然而,使用 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*/);
        // ...
    }
}

There is nothing wrong in using Java threads in Android but it is a bit overkill to use it just for sending periodic messages. The recommended way to do it is to use Handler.postDelayed. This article suggests following method: put all your updating code into a Runnable and add postDelayed call to the end of this Runnable's run() to schedule it again. This approach eliminates overhead of having a background thread.

However it is easy to use Handler to send messages from the other thread. As I understand you are trying to send messages to some UI component so it can update itself.
In my application I faced a similar problem. I declared a handler inside the UI component and passed this handler to a background thread in a constructor parameter.

The UI part looks like:

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();
    }
}

And the background thread is implemented like

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*/);
        // ...
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文