从服务访问UI线程处理程序
我正在尝试一些新的东西,我需要访问UI线程的处理程序。
我知道以下几点:
- UI线程有自己的处理程序和循环
- 任何消息将被放入UI线程的消息队列中
- 循环者拾取事件并将其传递给处理程序
- 处理程序处理消息并将特定事件发送到UI
我想有我的服务,必须获得UI线程处理程序,并将消息放入此处理程序。 所以这个消息将被处理,并将发布到用户界面。 这里的服务将是一个正常的服务,将由一些应用程序启动。
我想知道这是否可能。 如果是这样,请build议一些代码片段,以便我可以尝试。
问候Girish
这段代码构造了一个与主(UI)线程关联的Handler:
Handler handler = new Handler(Looper.getMainLooper());
然后,您可以在主(UI)线程中发布要执行的内容,如下所示:
handler.post(runnable_to_call_from_main_thread);
如果处理程序本身是从主(UI)线程创build的,则为简洁起见,可以省略参数:
Handler handler = new Handler();
关于进程和线程的Android开发指南有更多的信息。
创build一个连接到你的Handler
的Messenger
对象,并将该Messenger
传递给Service
(例如,在startService()
的Intent
extra中)。 然后Service
可以通过Messenger
将Message
发送给Handler
。 这是一个示例应用程序演示这个。
目前我更喜欢使用像Otto这样的事件总线库来处理这类问题。 只需订阅所需的组件(活动):
protected void onResume() { super.onResume(); bus.register(this); }
然后提供一个callback方法:
public void onTimeLeftEvent(TimeLeftEvent ev) { // process event.. }
然后当你的服务执行这样的语句:
bus.post(new TimeLeftEvent(340));
POJO将被传递给您的上述活动和所有其他订阅组件。 简单而优雅。
你可以通过广播接收器得到值……如下,首先创build你自己的IntentFilter,
Intent intentFilter=new IntentFilter(); intentFilter.addAction("YOUR_INTENT_FILTER");
然后创build内部类BroadcastReceiver为,
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { /** Receives the broadcast that has been fired */ @Override public void onReceive(Context context, Intent intent) { if(intent.getAction()=="YOUR_INTENT_FILTER"){ //HERE YOU WILL GET VALUES FROM BROADCAST THROUGH INTENT EDIT YOUR TEXTVIEW/////////// String receivedValue=intent.getStringExtra("KEY"); } } };
现在注册您的广播接收机onResume()as,
registerReceiver(broadcastReceiver, intentFilter);
最后取消注册onDestroy()中的BroadcastReceiver,
unregisterReceiver(broadcastReceiver);
现在最重要的部分…你需要从任何需要发送价值的地方播放广播…..所以,
Intent i=new Intent(); i.setAction("YOUR_INTENT_FILTER"); i.putExtra("KEY", "YOUR_VALUE"); sendBroadcast(i);
….干杯:)
解:
- 用主线程创build一个处理程序 :requestHandler
- 从主线程创build一个
Handler
与handleMessage
:responseHandler并重写handleMessage
方法 - 在requestHandler上发布一个Runnable任务
- 在
Runnable
任务中,调用responseHandler上的sendMessage - 这个
sendMessage
结果调用了responseHandler中的handleMessage。 - 从
Message
获取属性并处理它,更新UI
示例代码:
/* Handler from UI Thread to send request */ Handler requestHandler = new Handler(Looper.getMainLooper()); /* Handler from UI Thread to process messages */ final Handler responseHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { /* Processing handleMessage */ Toast.makeText(MainActivity.this, "Runnable completed with result:"+(String)msg.obj, Toast.LENGTH_LONG) .show(); } }; for ( int i=0; i<10; i++) { Runnable myRunnable = new Runnable() { @Override public void run() { try { /* Send an Event to UI Thread through message. Add business logic and prepare message by replacing example code */ String text = "" + (++rId); Message msg = new Message(); msg.obj = text.toString(); responseHandler.sendMessage(msg); System.out.println(text.toString()); } catch (Exception err) { err.printStackTrace(); } } }; requestHandler.post(myRunnable); }