@ExcitedSpider
2018-01-05T14:17:48.000000Z
字数 1590
阅读 1059
当一个app启动时,Android系统为这个app启动一个Linux进程(process)。在默认设置中,这个app的所有构件都使用这个进程中的一个线程(thread),称为主线程(main thread)。但是我们知道,app中有很多操作(比如网络io,外部存储io)是很耗时间的,如果把这些操作都放在主线程中,无疑会使app变得卡顿不堪,所以我们需要多线程。
在安卓sdk官方文档中,对主线程任务的定义是:渲染UI,响应交互事件并分配工作(到其他线程)。所以,主线程又可以称为UI线程。对于主线程,只要阻塞几秒钟,就会出现我们常见的"程序未响应"。所以主线程的流畅工作非常重要,不要在主线程上安排可能会需要大量时间和资源的工作。
同时,应该认识到主线程是自动创建的,和整个进程的生命长度相同。
工作线程,负责为主线程减负,承担需要大量时间和资源的工作,当其工作完成时,发送消息通知主线程,主线程接受消息后用工作线程处理好的资源进行工作。实现方法就是java的多线程。
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork("http://example.com/image.png");
}
}).start();
}
下载图片是一个比较耗时的工作,不要让主线程去做,让新的工作线程去做
应该提一点,android的设计师做了这样的设计:只有主线程才能操作UI(主要是为了防止内存泄漏),所以工作线程就不要越俎代庖了(包括发送Toast消息)。
android的这个设计是为了降低工作线程很多时的工作复杂度,message用来传递线程结束以及其他重要的消息,可以说是很优雅的设计了。
Bitmap b;
Arraylist list;
final Handler handler = new Handler(Looper.myLooper()) //消息处理类Handler
{//在主线程中,调用myLooper()获得主线程自带的Looper,实现循环处理
@override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0: //处理信息为0的工作线程的结束报告
mImageView.setImageBitmap(b);break;
case 1://处理信息为1的工作线程的结束报告
mListView.loadFromList(list);break;
}
}
};
new Thread(new Runnable() {
public void run() {
Message message=new Message();
message.what=0; //本线程记录信息0
b = loadImageFromNetwork("http://example.com/image.png");
handler.sendMessage(message);//发送给主线程,报告自己的工作做完了(下载图片),主线程可以用这张图片去渲染了
}
}).start();
new Thread(new Runnable() {
public void run() {
Message message=new Message();
message.what=1; //本线程记录信息1
readFromDataBase(list,sqLiteOpenHelper);//从数据库中读取信息
handler.sendMessage(message);//发送给主线程,报告自己的工作做完了(读取数据库),主线程可以用这个Arraylist去渲染列表了
}
}).start();