我在Android上尝试新的东西,我需要访问UI线程的处理程序。
我知道以下内容:
我希望我的服务必须获取UI线程处理程序并将消息放入此处理程序。 这样就可以处理此消息并将其发布到UI。 这里的服务将是一个正常的服务,将由一些应用程序启动。
我想知道这是否可行。 如果是这样,请建议一些代码片段,以便我可以尝试。
此致 吉里什
答案 0 :(得分:172)
这段代码构造了与主(UI)线程关联的处理程序:
Handler handler = new Handler(Looper.getMainLooper());
然后您可以在主(UI)线程中发布要执行的内容,如下所示:
handler.post(runnable_to_call_from_main_thread);
如果处理程序本身是从主(UI)线程创建的,为简洁起见,可省略参数:
Handler handler = new Handler();
进程和线程上的Android Dev Guide有更多信息。
答案 1 :(得分:28)
创建一个附加到Messenger
的{{1}}对象,并将Handler
传递给Messenger
(例如,Service
Intent
的额外内容})。然后,startService()
可以通过Service
向Message
发送Handler
。 Here is a sample application证明了这一点。
答案 2 :(得分:4)
目前我更喜欢使用Otto这样的事件总线库来解决这类问题。只需订阅所需的组件(活动):
protected void onResume() {
super.onResume();
bus.register(this);
}
然后提供回调方法:
public void onTimeLeftEvent(TimeLeftEvent ev) {
// process event..
}
然后当您的服务执行如下语句时:
bus.post(new TimeLeftEvent(340));
该POJO将传递给您的上述活动和所有其他订阅组件。简单而优雅。
答案 3 :(得分:2)
您可以通过广播接收器获取值......如下所示,首先创建您自己的IntentFilter,
Intent intentFilter=new IntentFilter();
intentFilter.addAction("YOUR_INTENT_FILTER");
然后创建内部类BroadcastReceiver as,
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()中注册您的广播接收器,
registerReceiver(broadcastReceiver, intentFilter);
最后在onDestroy()中取消注册BroadcastReceiver,
unregisterReceiver(broadcastReceiver);
现在最重要的部分......你需要从需要发送值的地方发射广播.....所以这样做,
Intent i=new Intent();
i.setAction("YOUR_INTENT_FILTER");
i.putExtra("KEY", "YOUR_VALUE");
sendBroadcast(i);
....欢呼:)
答案 4 :(得分:0)
解决方案:
Handler
创建Looper
:responseHandler并覆盖handleMessage
方法Runnable
内部任务中,在responseHandler sendMessage
结果。Message
获取属性并对其进行处理,更新用户界面示例代码:
/* 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);
}
答案 5 :(得分:0)
在kotlin
中,您可以做到
假设您要显示来自服务的Toast消息
val handler = Handler(Looper.getMainLooper())
handler.post {
Toast.makeText(context, "This is my message",Toast.LENGTH_LONG).show()
}
答案 6 :(得分:0)
我建议尝试以下代码:
new Handler(Looper.getMainLooper()).post(() -> {
//UI THREAD CODE HERE
});