Android 多线程编程以及异步消息处理机制学习

Android多线程编程

Android中对于耗时任务不应该在主(UI)线程中执行,一般需要新建子线程来执行这些耗时任务。
Android多线程编程不比Java特殊,基本用法是一样的,都是使用相同的语法。Android中定义一个线程可以使类继承致Thread或者时实现Runnable接口,然后重写run方法。

下面是一个例子:
class MyThread extends Thread{
    @Overwrite
    public void run(){
        //耗时任务
     }
}
使用:new MyThread().start();

实现Runnable接口
class MyThread implements Runnable{
    @Overwrite
    public void run(){
        //耗时任务
     }
}
使用:new Thread(new MyThread()).start();

如果不想实现Runnable接口也可以:
new Thread(new Runnable(){
    @Overwrite
    public void run(){
        //耗时任务
    }
}).start();

         Android的UI是线程不安全的,也就是说想要更新程序中的UI只能在UI线程,否则会出现异常。为什么限制只能在主线程中更改UI呢?原因是如果不限制的话,可能出现在两个或者两个以上的线程在同一时间操作某个UI控件,这个的话就会发生冲突。
        有时需要在子线程执行耗时任务,当执行完任务之后拿到结果需要去更新UI时,这个时候不能直接在子线程中更新UI。Android提供了一套异步消息机制,完美解决了子线程中更新UI操作的问题。

异步消息处理机制

Android中的异步消息处理机制主要由4个部分组成:Message、Handler、MessageQueue、和Looper。
1、Message
Message是线程之间传递的消息,它内部可以携带少量的信息,用于在不同的线程之间交换数据。
2、Handler
Handler是处理者的意思,它主要用于发送和处理消息。发送消息一般是使用Handler的sendMessage方法,消息经过一系列的辗转之后,会回到Handler的handMessage方法中。
3、MessageQueue
MessageQueue是消息队列的意思,它用于存放所有通过Handler发送的消息。Handler发送出来的消息会存放在MessageQueue中等待处理。每个线程只会有一个MessageQueue对象。
4、Looper
Looper是每个线程中MessageQueue的管家,调用Looper中的loop()方法后,就会进入到一个无限循环中,它会一直循环检查MessageQueue中是否还有消息,如果有,就将它取出来,送到Handler的handMessage方法中。每个线程也只有一个Looper对象。

异步消息处理机制中消息的传递流程是:首先在主线程中创建一个Handler对象,然后重写这个Handler对象的handMessage()方法。当子线程中需要更新UI时,就创建一个Message对象,将需要传递的数据信息保存在这个Message对象中,然后调用Handler对象的sendMessage()方法将这个Message对象添加到MessageQueue中,然后Looper在不断循环中就会发现这个消息,接着它就会把这个消息取出来处理,最后分发给Handler对象的handMessage()方法。这样就将消息从子线程转到了主线程。

这里需要注意一下,MessageQueue对象和Looper对象在每个线程中都只有一个,而主线程中的这两个对象时系统自动帮我们创建了的。我们无需自己创建。

runOnUiThread()方法实现的原来也是使用上述的异步消息机制。

既然这里说线程都可以有MessageQueue对象和Looper对象。那么考虑一个问题,是不是也可以在主线程中发送一个消息给子线程,然后子线程来处理呢?

答案是可以的,下面是一个示例

public class MainActivity extends AppCompatActivity {

        private static final String TAG = "MainActivity";
        private Handler myHandler ;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState) ;
            setContentView(R.layout. activity_main) ;
            Button sendMessageBtn = (Button) findViewById(R.id. btn_send_message) ;
            sendMessageBtn.setOnClickListener( new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                            Message message = new Message() ;
                            message. what = 12 ;
                            myHandler.sendMessage(message) ;
                    }
            }) ;
            childThread() ;
        }

        private void childThread(){
                new Thread( new Runnable() {
                    @Override
                    public void run() {
                         // 准备一个 Looper,Looper 创建时对应的 MessageQueue 也会被创建
                        Looper. prepare() ;
                        myHandler = new Handler(){
                                @Override
                                public void handleMessage(Message msg) {
                                        if (msg. what== 12){
                                                Log. d( TAG , "1351545454") ;
                                        }
                                }
                        } ;
                // Looper 开始不断的从 MessageQueue 取出消息并再次交给 Handler 执行  
                // 此时 Lopper 进入到一个无限循环中,后面的代码都不会被执行
                        Looper. loop() ;
                   }
                }).start() ;
        }
}





猜你喜欢

转载自blog.csdn.net/lin962792501/article/details/79109123