在我的项目中,我有一个永久运行的服务。
我还在这个服务中创建了 3 个线程,所以都在后台。他们每个人都做了一些工作,也请求 http 数据:我已经用 Handler 完成了,管理消息队列。
它很容易并且发展良好,增加了项目的维度和复杂性。
所以,是的,我应该这样做。
PS:如果你必须在后台工作,记得用PowerManager获取wake_locks,确保你在手机待机时CPU会保持开启(我花了几天时间才明白为什么手机待机时线程停止工作)。
在主线程中,我声明了4个处理程序(2个用于与recordingThread的两侧通信,2个用于与sendThread的两侧通信):然后简单地创建其他2个线程;看看 Looper 调用:当代码执行时不要让你的线程死掉,并等待传入的消息来自在它自己的执行内部创建的处理程序(在这种情况下是在 run() 方法中)。我还为与线程关联的每个处理程序声明了一个私有类:这样每个线程都有自己的通道来与不同的“动作”进行通信(切换案例)。还有另一个处理程序,recordingThread 处理程序,这里没有显示;但想法是一样的:
private Handler m_recordingThreadHandler, m_sendingThreadHandler,
m_thisRecordingThreadhandler, m_thisSendingThreadHandler;
public void run() {
Looper.prepare();
m_thisRecordingThreadhandler = new UpdRecHandler();
m_recordingThread = new RecordingThread(m_mainThreadContext,
m_thisRecordingThreadhandler, m_configuration, m_picturesDir);
m_recordingThread.setName("recordingThread");
m_recordingThread.start();
m_thisSendingThreadHandler = new UpdSenHandler();
m_sendingThread = new SendingThread(m_mainThreadContext,
m_thisSendingThreadHandler, m_configuration);
m_sendingThread.setName("sendingThread");
m_sendingThread.start();
Looper.loop();
}
private class UpdRecHandler extends Handler {
@Override
public void handleMessage(Message msg) {
Message m;
switch (msg.what) {
case Utils.SEND_THIS_THREAD_HANDLER:
Log.i(TAG, "Ricevuto Handler di recordingThread.");
m_recordingThreadHandler = (Handler) msg.obj;
m_recordingThreadReady = true;
checkForAllThreadsReady();
break;
case Utils.FORCE_RESET:
Log.i(TAG,
"RecordingThread ha compeltato la procedura per il reset.");
m_recordingThreadResetted = true;
checkForThreadsResetted();
break;
...more cases...
}
这段代码来自recordingThread 类。一旦创建,run 方法就会被执行,在这个方法中我将这个线程的处理程序传递给主线程(之前看到的代码),这个线程的处理程序是在这个 run() 方法中创建的:通过这种方式我启用了双向通信。同样,在recordingThread 中,我为处理程序创建了一个私有类。再次,一旦执行 run 方法,我已经将 Looper 调用让线程处于活动状态。
public void run() {
Looper.prepare();
Log.i(TAG, "In esecuzione, mando il mio handler a updateThread");
m_thisThreadHandler = new RecUpdHandler();
m_mainThreadHandler.obtainMessage(Utils.SEND_THIS_THREAD_HANDLER,
m_thisThreadHandler).sendToTarget();
Looper.loop();
}
private class RecUpdHandler extends Handler {
public void handleMessage(Message msg) {
Message m;
switch (msg.what) {
case Utils.TAKE_PHOTO:
...do work....
break;
case Utils.UPDATE_CONFIGURATION:
... do other work...
break;
}
如果你想让你的线程终止,你只需杀死与该线程关联的 Looper,如下所示:
Looper.myLooper().quit();
请记住,处理程序自动与创建它的线程关联:如果在线程 T1 中创建处理程序 A,那么您可以将 A 的引用传递给 T2 和 T3。然后这些线程能够向 T1 发送消息,但反之则不行。那是因为我创建了 4 个处理程序,用于启用 2 方通信。