Android基础之进程和线程 AsyncTask , Handler
2012-02-27 00:59
435 查看
进程Process
默认情况下,一个应用程序的所有组件都在一个进程之中.但也可以通过Manifest.xml文件中的android:process来指定某个<activity><service><provider><receiver>控件属于哪个进程,也可以为<application>指定进程
通过android:process可以让同一个应用的组件运行在不同的进程中,也可以使不同应用的组件运行在一个进程中
在系统内存较低的时候,Android系统会按一定规律选择性关闭一些进程.
线程Thread
不要阻塞UI线程(main线程)不要从UI线程之外的线程来操纵UI,比如imgView.setImageBitmap(...)等
从别的线程来更改UI时,可以用Activity.runOnUiThread(Runnable),View.post(Runnable),View.postDelayed(Runnable,long)
public void onClick(View v) { new Thread(new Runnable() { public void run() { final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png"); mImageView.post(new Runnable() { public void run() { mImageView.setImageBitmap(bitmap); } }); } }).start(); }
但遇到更加复杂的情形时会很乱,应该使用一个Handler或者继承AsyncTask类,
AsyncTask异步任务类
继承AsyncTask类时,不用自己去管理线程,onPreExcute是在调用前执行的块,onProgressUpdate,onPostExcute都是在原来的线程中进行的操作doInBackground是在新的线程中的操作,其返回值返回给了onPostExcute方法
任何时候都可以在doInBackground中使用publishProcess()方法来执行onProgressUpdate.
任何时候都可以取消新线程.
public void onClick(View v) { new DownloadImageTask().execute("http://example.com/image.png"); } private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { /** The system calls this to perform work in a worker thread and * delivers it the parameters given to AsyncTask.execute() */ protected Bitmap doInBackground(String... urls) { return loadImageFromNetwork(urls[0]); } /** The system calls this to perform work in the UI thread and delivers * the result from doInBackground() */ protected void onPostExecute(Bitmap result) { mImageView.setImageBitmap(result); } }
Handler
Handler的作用1.可以安排在未来的某时进行一些操作
2.在不同的线程中执行一些操作,并支持线程之间的通信
一个Handler对应着一个线程以及它的消息队列
当你创建一个Handler的时候,它就和创建它的线程/消息队列相绑定
之后,这个handler就要开始处理这个消息队列中的消息了
Looper是一个消息队列的监听器,并不是每一个thread都有looper,主线程在创建时,系统自动为其创建了looper,而用HandlerThread创建的Thread都有looper
可以构建Handler对象与Looper沟通,以便send新消息到messageQueue.
或者接收Looper从MessageQueue中取出的消息.
在子线程中使用主线程的Handler发送消息(向主线程的MessageQueue发送消息)
拿一个常用的功能举例子:比如要从网络上获得一张图片,并且更新到当前Activity的imageView上
首先要新建一个线程,在其run方法中来从网络上下载图片 //下载这种操作比较费时,当然要用异步
在Activity中调用这个线程.start()来启动线程
在线程中下载完成时引用主线程的handler.sendMessage()来通知主线程下载好了开始更新 //在这个功能中handler是主线程的,消息队列也是主线程的,此时的主线程没有必
要有handler和looper,也就没必要用HandlerThread,普通的Thread即可
在主线程的handler中的handleMessage方法中更新UI //handler是主线程的,当然里面的handleMessage方法也在主线程中执行,在UI线程中更新UI
具体实现如下:
在Activity中:
Handler activityHandler=new Handler(){ //因为handler需要重写handlMessage方法来决定其处理消息的方式,要new一个
public void handleMessage(Message msg){
if(msg.arg1==UPDATE_UI){
imageView.setBitmap(....); //如果接受的消息一个参数是UPDATE_UI常量,更新UI
}
}
}
启动一个新的线程:
class ImageThread extends Thread{
public void run(){
//从网络上获得图片
//获得完毕之后
Message msg=new Message(); //生成一个消息对象
msg.arg1=UPDATE_UI; //设置其参数
activityHandler.sendMessage(msg); //调用主线程的activityHandler,向主线程的消息队列发送消息
//或者这里调用
}
}
ImageThread it=new ImageThread();
it.start();
所以如果两个线程之间要相互通信,就要两个线程都拥有handler,looper,消息队列了
而还有handler.post(Runnable) postDelayed(Runnable,long)等,这些线程执行都是在调用它们的handler所在线程执行的
一些简单的实验:
//创建一个Hanlder对象
Handler handler=new Handler();
//把所要进行操作的线程对象用handler.post()或者.postDealyed()方法添加到线程队列中
handler.post(updateThread); //handler.removeCallbacks(updateThread)来从消息队列中去除掉这个线程
Runnable updateThread =new Runnable(){
public void run(){
//线程中的复杂操作
System.out.println("Thread Start");
}
}
//下面这个是可以处理消息的Handler
Handler handler=new Handler(){
public void handleMessage(Message msg){
System.out.println(msg.arg1+"");
}
}
handler.post(updateThread); //把新线程加入到消息队列中
Runnable updateThread=new Runnable(){
public void run(){
Message msg=handler.obtainMessage(); //获得handler中消息队列的一个消息
msg.arg1=50; //为msg携带的值赋值
handler.sendMessage(msg); //把消息加入handler的消息队列
}
}
但是上述两个Handler其实都没有真正的启动另外的线程,而还是在原来的main线程中执行!!!!
如果要使用Handler来生成新线程来执行复杂操作可以使用HandlerThread类,
HandlerThread类会启动一个带有looper的新的线程,而这个looper一会儿可以用来创建Handler
HandlerThread handlerThread=new HandlerThread("handler_thread"); //创建一个HandlerThread线程对象,如果要执行有意义的操作,继承这个类,重写run方法
handlerThread.start();
MyHandler myHandler=new MyHandler(handlerThread.getLooper()); //用新线程的looper来创建一个handler对象
Message msg=myHandler.obtainMessage();
msg.sendToTarget();
class MyHandler extends Handler{
public void handleMessage(Message msg){
}
}
相关文章推荐
- 【Android开发】线程间通讯机制(基础篇)——Handler、Runnable、HandlerThread、AsyncTask的使用
- 【Android开发】线程间通讯机制(基础篇)——Handler、Runnable、HandlerThread、AsyncTask的使用
- Android中的进程与多线程的讲解(Handler和AsyncTask)
- 【代码】Android中的进程与多线程的讲解(Handler和AsyncTask)
- android进程与线程详解三:AsyncTask
- android进程与线程详解三:AsyncTask
- Android线程交互(Handler+Thread 和 AsyncTask)
- android基础--handler与线程
- Android 基础总结:( 十七)线程和进程
- [译]Android应用程序基础 >> 进程和线程(Processes and Threads)
- Android进程线程---Anynctask(本质还是Handler)
- Android -- 线程通信之AsyncTask、Handler
- Android 不可缺少的异步(Thread、Handler、AsyncTask)实例解析(在独立线程中进行地理位置编码)
- Android基础之单线程模型中Message、Handler、Message Queue、Looper之间的关系
- Android基础知识学习之线程通信(Handler学习)
- Android 线程Handler与异步加载AsyncTask的比较
- android 线程(AsyncTask,Threadhandler,intentService)详解
- android进程与线程详解三:AsyncTask
- android进程与线程详解三:AsyncTask
- android基础学习006_android AsyncTask 和 Handler 介绍