在本篇文章中将会介绍到的内容有:
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的介绍和使用