从服务访问UI线程处理程序



我正在Android上尝试一些新的东西,为此我需要访问UI线程的处理程序。

我知道以下内容:

  1. UI线程有自己的处理程序和活套
  2. 任何消息都将被放入进入UI的消息队列螺纹
  3. 活套接收事件并将其传递给处理程序
  4. 处理程序处理消息和将特定事件发送到UI

我想要我的服务,它必须获得UI线程处理程序并将消息放入该处理程序。以便处理此消息并将其发送到UI。这里的服务将是一个正常的服务,它将由一些应用程序启动。

我想知道这是否可能。如果是的话,请建议一些代码片段,这样我就可以尝试了。

问候Girish

这段代码构建了一个与主(UI)线程相关的处理程序:

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

然后,您可以在主(UI)线程中发布要执行的内容,如下所示:

handler.post(runnable_to_call_from_main_thread);

如果处理程序本身是从主(UI)线程创建的,那么为了简洁起见,可以省略参数:

Handler handler = new Handler();

关于进程和线程的Android开发人员指南提供了更多信息。

创建一个附加到HandlerMessenger对象,并将该Messenger传递给Service(例如,在startService()的额外Intent中)。CCD_ 7然后可以经由CCD_ 10向CCD_ 9发送CCD_。下面是一个示例应用程序来演示这一点。

我建议尝试以下代码:

    new Handler(Looper.getMainLooper()).post(() -> {
        //UI THREAD CODE HERE

    });

目前,我更喜欢使用Otto等事件总线库来解决此类问题。只需订阅所需组件(活动):

protected void onResume() {
    super.onResume();
    bus.register(this);
}

然后提供一个回调方法:

public void onTimeLeftEvent(TimeLeftEvent ev) {
    // process event..
}

然后当你的服务执行这样的语句时:

bus.post(new TimeLeftEvent(340));

该POJO将传递给您的上述活动和所有其他订阅组件。简洁优雅。

您可以通过广播接收器获取值。。。。。。如下所示,首先创建自己的IntentFilter作为

Intent intentFilter=new IntentFilter();
intentFilter.addAction("YOUR_INTENT_FILTER");

然后将内部类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()中将您的广播接收器注册为

registerReceiver(broadcastReceiver, intentFilter);

最后在onDestroy()中将BroadcastReceiver注销为

unregisterReceiver(broadcastReceiver);

现在最重要的部分。。。您需要从任何需要发送值的地方启动广播。。。。。

Intent i=new Intent();
i.setAction("YOUR_INTENT_FILTER");
i.putExtra("KEY", "YOUR_VALUE");
sendBroadcast(i);

欢呼:)

kotlin中,就是这样做的

比方说,如果你想显示来自服务的Toast消息

val handler = Handler(Looper.getMainLooper())
handler.post {
   Toast.makeText(context, "This is my message",Toast.LENGTH_LONG).show()
}

解决方案:

  1. 从主线程创建一个带有Looper的处理程序:requestHandler
  2. 从Main Thread:responseHandler创建一个带有LooperHandler并重写handleMessage方法
  3. 在requestHandler上发布可运行任务
  4. Runnable任务中,调用responseHandler上的sendMessage
  5. sendMessage导致调用responseHandler中的handleMessage
  6. 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);
    }

相关内容

  • 没有找到相关文章

最新更新