android学习笔记——android多线程编程初探

来源:互联网 发布:剑桥大学研究生 知乎 编辑:程序博客网 时间:2024/04/29 18:01
在本篇文章中将会介绍到的内容有:
1.介绍多线程用处
2.线程的基本用法
3.简单讲解异步消息处理机制(用于更新UI)

1.多线程
当我们需要执行一些耗时操作时,如果单纯的将耗时操作交给主线程去做,那么有可能别的一些更需要主线程做的任务就被耽搁了(如UI的更新),导致了主线程被阻塞,影响了用户对软件的正常使用。所以需要将一些耗时的操作分配给子线程去做,提高软件的友好性。

2.线程的基本用法
线程的基本用法主要有3种:

(1)写个类继承Thread,然后重写父类的run()方法,在其中写上耗时逻辑
     class MyThread extends Thread{
          @Override
          public void run(){
               //处理具体的逻辑
          }
     }
启动该线程的方法:
     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();

3.简单讲解异步消息处理机制(用于更新UI)
首先要明确的一点是在android中对于UI的更新,是不允许在子线程中执行的,会发生错误,只能在主线程中进行执行。子线程中做耗时的操作,在主线程中做UI的更新。
用一个小的demo介绍一下
public class HandlerActivity extends Activity {

public static final int UPDATE_TEXT = 1;
private Button mButton;
private TextView mTextView;
private Handler handler = new Handler(){

//处理消息在主线程中
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub

switch (msg.what) {
case UPDATE_TEXT:
     mTextView.setText("it is changed");
     break;

default:
     break;
}
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_handler);

mButton = (Button)findViewById(R.id.change_text);
mTextView = (TextView)findViewById(R.id.handle_textView);

mButton.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread(new Runnable() {

//子线程运行下面的代码
@Override
public void run() {
// TODO Auto-generated method stub
Message message = new Message();
message.what = UPDATE_TEXT;
handler.sendMessage(message);

//子线程运行耗时操作,修改UI的操作放在handler的主线程中处理
try {
     Thread.sleep(1000);
} catch (InterruptedException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
}
}
}).start();
          }
});
}
}

上述的异步消息处理机制需要我们理解4个概念,handler、message、MessageQueue、looper
  • handler : 是整个异步消息处理机制中的控制者,处理者。它负责发送和处理消息
  • message : 主要是在不同的线程之间传递消息,作为一个消息的载体,其中的what字段等等,可以携带一定的数据信息。
  • MessageQueue: 消息队列,整个程序可能有很多异步消息需要处理,但是对于一个线程来说(主线程),只能有一个handler ,MessageQueue。所以我们需要把还没有处理的消息放入消息队列当中。
  • looper:它相当于MessageQueue中的调度者,通过调用loop方法,进行一个无限循环,不断的从消息队列中取出消息,发送给 handler进行处理。
我们再对异步消息处理的流程梳理一遍。首先要在主线程中创建一个Handler对象,并重写handleMessage()方法。然后当子线程需要更新UI时,就创建一个Message对象,通过Handler对象将这条信息发送出去。之后这条信息会被添加到MessageQueue队列中等待被处理,而Looper会一直尝试从MessageQueue中取出待处理消息,分发回Handler的handleMessage()方法中去。由于Handler是在主线程中创建的,所以此时handleMessage()方法也是在主线程中运行的,于是我们可以放心的更新UI操作。
关于Handler异步消息处理机制的简单讲解可以查看:http://android.jobbole.com/80853/
深入讲解可查看:http://blog.csdn.net/lmj623565791/article/details/38377229(比较深入,还不怎么明白)
对于异步消息处理机制,android中还提供了一个AsyncTask,这个机制更加简洁方便,详细可参考:http://www.cnblogs.com/suinuaner/archive/2013/04/11/android_fifty.html   (demo中有一句问题,要注意)
也可参看我下一篇关于AsyncTask的介绍和使用

0 0
原创粉丝点击