当前位置: 代码迷 >> Android >> Android Framework系列之IPC(2)
  详细解决方案

Android Framework系列之IPC(2)

热度:23   发布时间:2016-05-01 16:49:31.0
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代码??收藏代码
  1. package?waterlife.ipc.demo;??
  2. ??
  3. import?java.io.InputStream;??
  4. import?java.net.MalformedURLException;??
  5. import?java.net.URL;??
  6. import?java.net.URLConnection;??
  7. ??
  8. import?android.app.Activity;??
  9. import?android.os.AsyncTask;??
  10. import?android.os.Bundle;??
  11. import?android.widget.ProgressBar;??
  12. ??
  13. public?class?myAsyncTask?extends?Activity?{??
  14. ????static?ProgressBar?pb;??
  15. ????/**?Called?when?the?activity?is?first?created.?*/??
  16. ????@Override??
  17. ????public?void?onCreate(Bundle?savedInstanceState)?{??
  18. ????????super.onCreate(savedInstanceState);??
  19. ????????setContentView(R.layout.main);??
  20. ????????pb?=?(ProgressBar)findViewById(R.id.ProgressBar01);??
  21. ????????Download?dl?=?new?Download();??
  22. ????????dl.execute();??
  23. ????}??
  24. ????????
  25. ????public?class?Download?extends?AsyncTask<Void,?Integer,?Void>??
  26. ????{??
  27. ??
  28. ????????@Override??
  29. ????????protected?Void?doInBackground(Void...?params)?{??
  30. ????????????//?TODO?Auto-generated?method?stub??
  31. ????????????int?totalSize?=?0;??
  32. ????????????InputStream?recevier?=?null;??
  33. ????????????try?{??
  34. ????????????????URL?myUrl?=?new?URL("http://bbs.nju.edu.cn/");??
  35. ??
  36. ????????????????URLConnection?urlConn?=?myUrl.openConnection();??
  37. ????????????????totalSize?=?urlConn.getContentLength();??
  38. ????????????????recevier?=?urlConn.getInputStream();??
  39. ????????????????byte[]?b?=new?byte[256];??
  40. ????????????????int?length?=?0;??
  41. ????????????????length?+=?recevier.read(b);??
  42. ????????????????while(length?<?totalSize)??
  43. ????????????????{??
  44. ????????????????????length?+=?recevier.read(b);??
  45. ????????????????????publishProgress((int)(length*100/totalSize));??
  46. ????????????????}??
  47. ????????????????recevier.close();??
  48. ????????????}?catch?(MalformedURLException?e)?{??
  49. ????????????????//?TODO?Auto-generated?catch?block??
  50. ????????????????e.printStackTrace();??
  51. ????????????}catch?(Exception?ex)??
  52. ????????????{??
  53. ????????????????ex.printStackTrace();??
  54. ????????????}??
  55. ????????????return?null;??
  56. ????????}??
  57. ??????????
  58. ????????protected?void?onProgressUpdate(Integer...?progress)?{??
  59. ????????????pb.setProgress(progress[0]);??
  60. ????????}??
  61. ????}??
  62. }??

在这个Demo中只有第二和第三步,只有第二个参数params,是一个整型参量,把下载数据包的进度更新给UI Progressbar显示。

?

另外,使用AsyncTask需要注意以下几点:

1.?AsyncTask的实例只能在UI线程中创建;

2. dl.execute()方法只能在UI线程中调用,并且只能调用一次,否则会抛异常。

  相关解决方案