Android线程间通信
  • 时间:2019-11-19

Android 体系中,运用在运转时是一个独立的进程,可是每个进程中能够包括多个觊发k8旗舰厅线程进步运转功率。在多线程开发中,有一个很重要的准则:不能在子线程中更新 UI 。

Only the original thread that created a view hierarchy can touch its views.

为处理这个问题,现在有多重计划完成子线程和主线程之间的通讯。

在一些简略代码逻辑中,或许能够很明晰的区分出运转在子线程或主线程中。通常在杂乱的类联系依靠、函数嵌套调用中,或许需求花费很大精力去阅览代码之后去判别。不过,巧法子也是有的,一行代码处理。

Log.d;
仿制代码

日志内容中,2368-2393 表明是在子线程中输出日志。

11-16 01:08:31.584 2368-2393/com.flueky.demo D/TAG: test

其间 2368 表明 PID 指进程id, 2393 表明 TID 指线程id 。假如 TID 也是 2368 ,则表明日志输出在主线程中。

或许也有人听过 UID ,运用第一次装置在设备上时,体系会分配一个序号给运用,作为其仅有标识。UID 在掩盖装置时不会改变,卸载装置时体系会重新分配一个。

下面是在代码中获取三个 id 的办法。

// 获取 tid
Process.myTid
// 获取 pid
Process.myPid
// 获取 uid
Process.myUid
仿制代码

遇到需求在子线程中更新 UI 操作时,能够经过下面的这些办法处理。

子线程代码运转在 Activity 或 Fragment 中,能获取到恣意 view 的引用时,能够运用此办法将需求完成的代码放在主线程中运转。

// post 办法在子线程中调用
textView.post {
 @Override
 public void run {
 // 此处代码会在 UI 线程履行
仿制代码

假如能够直接获取到 Activity 实例,运用 runOnUiThread 办法。

// runOnUiThread 办法在子线程中调用
activity.runOnUiThread {
 @Override
 public void run {
 // 此处代码会在 UI 线程履行
仿制代码

运用 Handler 比较考究,因为需求考虑到 Handler 实例初始化的方位。

// post 办法在子线程中调用
handler.post {
 @Override
 public void run {
 // handler 在主线程中初始化时,此处代码在主线程中履行
 // handler 在子线程中初始化事,此处代码在子线程中履行
仿制代码

以上说法其实不行谨慎,存在下面的状况,初始化 handler 实例时传入 Looper.getMainLooper ,则 handler.post 也在主线程中履行。

// 下面的代码在子线程中履行
Looper.prepare;
handler = new Handler);
Looper.loop;
仿制代码

EventBus 出自 greenrobot ,经过订阅的办法,奉告函数运转在哪个线程中。为使订阅函数在主线程中履行,运用注解 MAIN 或 MAIN_ORDERED 。

/**
 * eventbus 简略示例
public class MainActivity extends Activity {
 @Override
 protected void onCreate {
 super.onCreate;
 setContentView;
 * 订阅函数,
 * ThreadMode.MAIN 表明在主线程中运转,或许会阻塞子线程。
 * ThreadMode.MAIN_ORDERED 表明在主线程中运转,不会阻塞子线程。
 @Subscribe
 public void onMessageEvent {
 if
 event).run;
 @Override
 protected void onStart {
 super.onStart;
 // 注册 eventbus 监听
 EventBus.getDefault.register;
 @Override
 protected void onStop {
 super.onStop;
 // 刊出 eventbus 监听
 EventBus.getDefault.unregister;
// 在子线程中发送音讯
EventBus.getDefault.post {
 @Override
 public void run {
 // 此处代码会在 UI 线程履行
仿制代码

前面四种办法演示了如安在子线程中做更新 UI 操作。 AsyncTask 也具有相同用法,可是有点勉强,因为只要 execute 办法在主线程中履行,onPostExecute 才会在主线程中调用。因为 onPostExecute 能够接收到子线程传递的恣意类型的目标数据,所以 AsyncTask 能够作为线程间的数据交互的载体。对此 Handler 和 EventBus 表明不服。

EventBus 如之前所示,能够将 Runnable 目标换成恣意实例。

Handler 也能够经过 sendMessage 办法发送 Message 目标。其间 Message.obj 用作传递目标数据的载体。

主张运用 Message.obtain 办法复用 Message 实例。

趁便提下,BroadcastReceiver 也能够作为此类用处,只不过没有 EventBus 和 Handler 便利。

觉得有用?那打赏一个呗。去打赏

个人主页现已更新 ,欢迎保藏flueky.github.io/。


客服QQ: 点击这里
地址: 客服QQ:
Copyright © 2018 觊发k8旗舰厅觊发k8旗舰厅-凯发k8官方网站-凯发k8官网 All Rights Reserved

服务时间:7X10小时