Android线程间通信runOnUiThread

定义:
Android线程间通讯(主要是子线程与UI主线程之间通信,子线程发送消息给UI主线程,主线程对界面进行相应的更新)
原理
基于Handler,在Handler的基础上进行封装,Handler的使用如下:
1、Main Thread 中实现Handler类
2、子线程中拥有Main Thread中Handler类的对象mHandler
3、子线程发送消息给主线程mHandler.sendMessage(Message msg)
4、通过Looper循环机制,主线程Handler类中的handleMessage(Message msg)处理子线程发送来的数据
runOnUiThread()的使用

  • runOnUiThread()是Activity类中的方法,它用于从子线程中切换到主线程来执行一些需要再主线程执行的操作。

  • runOnUiThread()的参数是Runnable。

这里先直接看一个例子,看看它是如何使用的:

public class MainActivity extends AppCompatActivity {
    
    
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.tv_test);
        new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                //do something takes long time in the work-thread
                runOnUiThread(new Runnable() {
    
    
                    @Override
                    public void run() {
    
    
                        textView.setText("test");
                    }
                });
            }
        }).start();
    }
}

原理分析:
使用简单,其原理也非常简单,底层实际上也是封装的Handler来实现的,如下是Activity类的关键代码:

//=========Activity=========
final Handler mHandler = new Handler();

private Thread mUiThread;

final void attach(...{
    
    
    ......
    mUiThread = Thread.currentThread();
    ......
}

/**
 * Runs the specified action on the UI thread. If the current thread is the UI
 * thread, then the action is executed immediately. If the current thread is
 * not the UI thread, the action is posted to the event queue of the UI thread.
 *
 * @param action the action to run on the UI thread
 */
public final void runOnUiThread(Runnable action) {
    
    
    if (Thread.currentThread() != mUiThread) {
    
    
        mHandler.post(action);
    } else {
    
    
        action.run();
    }
}

mHander是Activity的成员变量,在Activity实例化的时候也跟着初始化了,MainActivity继承自Activity,这里mHandler使用的looper自然是main looper了。
attach方法也是在主线程中调用的,mUiThread就表示主线程了。
runOnUiThread(Runnable action)源码的理解如下:
如果该方法是运行在主线程,Runnable的run方法会马上运行;而如果不是在主线程,就post到主线程的looper的MessageQueue中排队执行。

为什么参数是Runnable?Runnable如何转为Message并通过Handler将数据发送出去?
我们来看下Handler的post函数的源码如下:

   public final boolean post(@NonNull Runnable r) {
    
    
       return  sendMessageDelayed(getPostMessage(r), 0);
   }
    
 @UnsupportedAppUsage
    private static Message getPostMessage(Runnable r, Object token) {
    
    
        Message m = Message.obtain();
        m.obj = token;
        m.callback = r;
        return m;
    }

由上面两个方法的代码可以看出,通过getPostMessage方法将Runnable转为Message,然后通过sendMessageDelayed方法将Message发送给主线程执行。

参考链接:

https://www.cnblogs.com/andy-songwei/p/12064596.html

猜你喜欢

转载自blog.csdn.net/li1500742101/article/details/113615847
今日推荐