关于Android多线程编译

Android多线程编译的问题一直都是HR青睐的面试题,因为多线程编译在Android开发过程中占有一定的地位。如果我们把一个耗时操作放在主线程中,就会导致主线程被阻塞,影响软件的正常使用。所以我们一般会把一个耗时任务放在一个子线程中,那如果是多个耗时任务呢?所以就有了多线程编译。

Android中是怎么创建一个线程的呢?办法有三个:

1.新建一个类继承自Thread,然后重写父类的run()方法,然后把耗时逻辑编写在里面,如:

class MyThread extends Thread{
        @Override
        public void run() {
            super.run();
            //处理逻辑写这里
        }
    }

然后我们通过new一个MyThread的实例,调用start()方法:new MyThread().start();

2.我们还可以通过去实现Runnable接口的方法去定义一个线程,如:

 class MyThread implements Runnable{
        @Override
        public void run() {
            //处理逻辑写这里
        }
    }

因为是这个方法是实现了接口,所以启动线程的方法有所调整:

MyThread  mythread = new MyThread()

new Thread(mythread).start();

3.最常见的方法就是使用匿名类去创建一个线程,如:

      new Thread(new Runnable() {
            @Override
            public void run() {
                //处理逻辑写这里
            }
        }).start();

       通过上面的学习你已经对线程的创建和使用有了一定的了解,那么你是否知道在Android中,UI的更新是不能在子线程中进行的。Android的UI线程是不安全的,我们要更新应用程序的UI元素,必须在主线程中进行,否侧就会出现异常。那么我们怎么样才能在子线程中进行UI操作呢?

        对于以上的问题Android提供了一套异步消息处理机制,完美地解决了在子线程中进行UI操作,那就是大家都应该有所耳闻的异步消息处理机制。下面是异步消息处理机制流程示意图:

扫描二维码关注公众号,回复: 1780805 查看本文章


此图是百度找的,如若有侵权请联系版主删除图片

        从图中可以看出Android异步消息处理机制主要由4个部分组成:Message、Handler、MessageQueue、Looper。现在我们来认识认识这四个部分先。

1.Message

        Message是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。它能使用的字段有what、arg1、arg2、obj这四个,用法如:Message.what。

2.Handler

        Handler主要是用于发送和处理消息的。Handler提供sendMessage()方法让开发者发送信息并最终传递到Handler的handlerMessage()方法中。

3.MessageQueue

        MessageQueue主要是用于存放所有通过Handler发送的消息,它相当于一个消息队列。要记住的是每个线程只会有一个MessageQueue对象。

4.Looper

        Looper是用于管理MessageQueue,它提供了一个loop()方法无限循环的在MessageQueue中取出消息,并把消息传递到Handler的handlerMessage()方法中。而且每个线程中也只会有一个Looper对象。

        现在我们应该对这四个部分有了初步的了解了,现在我们来捋捋Android异步消息处理机制的整个流程。首先要在主线程当中创建一个Handler对象,并重写handlerMessage()方法。然后当子线程中有需要进行UI操作时,就要创建一个Message对象,并通过Handler对象的sendMessage()方法把这条消息发送出去。之后这调消息会存储在MessageQueue的队列中等待被处理,而Looper此时会一直尝试从MessageQueue中取出待处理的消息,最后分发回Handler的handlerMessage()方法中。但是由于Handler是在主线程中创建的,所以此时handlerMessage()方法中的代码也会在主线程中运行,这样就能达到了我们想要的效果,这就是异步消息处理的核心思想。弄懂了原理后我们在代码上实现一下看看效果是不是如我们所想,上个最简单的例子,我们做一个能通过点击按钮然后改变文本控件显示的内容的功能来试试。上代码图:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    final static int CHANGE_TEXT = 1;//先定义一个整型变量来表示更新TextView这个动作
    private Button bt_change;
    private TextView tv_texr;
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case CHANGE_TEXT:
                    tv_texr.setText("我变了");//接收到消息后改变textview里面的文本
            }
        }
    };//创建Handler对象在主线程
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt_change = (Button) findViewById(R.id.bt_change);
        tv_texr = (TextView)findViewById(R.id.tv_text);
        bt_change.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.bt_change:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Message message = new Message();//实例化一个Message对象
                        message.what = CHANGE_TEXT;//通过what字段存储消息
                        handler.sendMessage(message);//使用handler对象的sendMessage方法把这条消息发送到handlerMessage方法中
                    }
                }).start();//通过创建一个匿名类的方式去创建一个子线程
                break;

        }
    }


}

        上面代码的基本思路是:先定义一个整型变量CHANGE_TEXT,用于表示更新TextView的文本内容这个动作。然后实例化一个Handler对象,并重写handlerMessage()方法,对发送的Message的what字段进行处理,如果等于CHANGE_TEXT,就将TextView显示的文本内容进行相应的变化。那我们的Message是从哪来的呢?这里我实现了点击监听事件的接口,当我们点击bt_change这个按钮时,我们就以匿名类的方式创建一个子线程,并在子线程中实例化一个Message对象。之后我们把Message对象的what字段的值指向了CHANGE_TEXT,然后调用Handler的sendMessage()方法把这个消息发送出去。这样就完美的解决了在子线程中更新UI界面的功能了。

        当然大家如果有兴趣的话,其实Android还提供了另外一个可以处理异步消息的工具——AsyncTask,你们可以去了解了解一下这个工具。它不需要你去深入了解异步消息处理机制,也可以在子线程切换到主线程。但是它其实实现的原理都一样,只是Android帮我们做好了封装,我们可以直接使用它而不需要懂其中的运行原理,我在这里就不详细介绍了。

转载的小伙伴请表明原创出处:原创链接


猜你喜欢

转载自blog.csdn.net/weixin_40600325/article/details/80229108