Android Framework系列之IPC(2)
Android Framework系列之IPC(二)对于Android的IPC来说,除了Handler和Looper之外,还有另外一种简便的方法来
Android Framework系列之IPC(二)
对于Android的IPC来说,除了Handler和Looper之外,还有另外一种简便的方法来实现多线程的通信,那就是AsyncTask。AsyncTask是一个异步的方法,它允许背景运算并把结果更新到前台的UI线程之上。要实现一个AsyncTask主要有4个步骤,但并不是每一个步骤都是必需的。
?
这四个步骤是:
onPreExecute()?执行背景运算前任务的初始化;
doInBackground(Params...)这是AsyncTask最核心的函数,即是做背景运算;它在第一步完成之后被调用,通常在这步中还会调用方法publishProgress(Progress...)将运算结果更新到UI主线程上;
onProgressUpdate(Progress...)是在publishProgress(Progress...)调用之后被执行的,需要注意到是这步执行的时间是未定的,通常在这一步中会更新相关UI;
onPostExecute(Result)这一步同样是和UI相关,将运算结果Result当作参数传递给UI。
?
大家可能已经注意到AsyncTask除了四大步之外,还有三个重要的参数:AsyncTask<Params,?Progress,?Result>。三个参数为通用类型,Params是传给任务初始化的参数,Progress是做背景运算过程中和UI交互的参数,Result是背景运算传递给UI的结果。
?
利用好这四大步和三个参数,我们可以方便的写出上节例子中的Demo:
Java代码??

- package?waterlife.ipc.demo;??
- ??
- import?java.io.InputStream;??
- import?java.net.MalformedURLException;??
- import?java.net.URL;??
- import?java.net.URLConnection;??
- ??
- import?android.app.Activity;??
- import?android.os.AsyncTask;??
- import?android.os.Bundle;??
- import?android.widget.ProgressBar;??
- ??
- public?class?myAsyncTask?extends?Activity?{??
- ????static?ProgressBar?pb;??
- ????/**?Called?when?the?activity?is?first?created.?*/??
- ????@Override??
- ????public?void?onCreate(Bundle?savedInstanceState)?{??
- ????????super.onCreate(savedInstanceState);??
- ????????setContentView(R.layout.main);??
- ????????pb?=?(ProgressBar)findViewById(R.id.ProgressBar01);??
- ????????Download?dl?=?new?Download();??
- ????????dl.execute();??
- ????}??
- ????????
- ????public?class?Download?extends?AsyncTask<Void,?Integer,?Void>??
- ????{??
- ??
- ????????@Override??
- ????????protected?Void?doInBackground(Void...?params)?{??
- ????????????//?TODO?Auto-generated?method?stub??
- ????????????int?totalSize?=?0;??
- ????????????InputStream?recevier?=?null;??
- ????????????try?{??
- ????????????????URL?myUrl?=?new?URL("http://bbs.nju.edu.cn/");??
- ??
- ????????????????URLConnection?urlConn?=?myUrl.openConnection();??
- ????????????????totalSize?=?urlConn.getContentLength();??
- ????????????????recevier?=?urlConn.getInputStream();??
- ????????????????byte[]?b?=new?byte[256];??
- ????????????????int?length?=?0;??
- ????????????????length?+=?recevier.read(b);??
- ????????????????while(length?<?totalSize)??
- ????????????????{??
- ????????????????????length?+=?recevier.read(b);??
- ????????????????????publishProgress((int)(length*100/totalSize));??
- ????????????????}??
- ????????????????recevier.close();??
- ????????????}?catch?(MalformedURLException?e)?{??
- ????????????????//?TODO?Auto-generated?catch?block??
- ????????????????e.printStackTrace();??
- ????????????}catch?(Exception?ex)??
- ????????????{??
- ????????????????ex.printStackTrace();??
- ????????????}??
- ????????????return?null;??
- ????????}??
- ??????????
- ????????protected?void?onProgressUpdate(Integer...?progress)?{??
- ????????????pb.setProgress(progress[0]);??
- ????????}??
- ????}??
- }??
在这个Demo中只有第二和第三步,只有第二个参数params,是一个整型参量,把下载数据包的进度更新给UI Progressbar显示。
?
另外,使用AsyncTask需要注意以下几点:
1.?AsyncTask的实例只能在UI线程中创建;
2. dl.execute()方法只能在UI线程中调用,并且只能调用一次,否则会抛异常。