说到线程,大家都知道,可以当作android进程的一个轻量级的表现,只是不占有空间和资源。在android中,有一个线程是我们最常接触到的,当我们做的一个应用,在第一次进入的时候,进入第一个Activity的时候,android自身就会自动创建一个用于控制一些控件以及绘图的MainUI线程,也就是我们说的activity主线程。

  说到这里,就不得不提到一个概念,它就是消息队列,由于activity 的主线程里面已经给我们准备好了消息队列,所以我们只需要在用的时候直接用就可以了,但在自己创建的子线程里面却不行,因为子线程本身并没有消息队列这个东西,在我们做线程交互的时候,刷新主界面的时候,往往是通过Handle来完成的,这里不得不提到另一个东东,它叫LOOP,当我们从子线程里面,通过handle来发送一个消息出来之后,LOOP会把这个消息发送回到主线程里面,然后通过消息队列的方法,来处理这些消息,最终达成我们刷新主界面的效果。

  那如何在我们自己创建的子线程里面实现消息队列,很简单,调用Looper.prepare(),那么系统就会自动的为该线程建立一个消息队列,然后调用 Looper.loop();之后就进入了消息循环,这个之后就可以发消息、取消息、和处理消息。这个方法对于平常,我们自己一些用来控制线程交互的实现,非常有用,所以分享一下。

  说到这里,可能大家时常会遇到一些handle之后,好像没用的现象,这是因为,handle之后,LOOP把消息传到了消息队列的尾部,这是没有问题的,但是在处理端的时候,就有可能会出现阻塞的现象,所以,用handle来处理一些复杂的图象更新的时候,有时候有出现一些不可靠的现象。但Handle本身有自己的优势,就是使用简单,易懂,而且对于一般应用来说,出错的情况并不是很频繁,所以使用也就特别多。

  有可能大家会问,什么是可靠的呢,这里就不得不提到另一个东西,叫AsyncTask,简单来说,就是异步任务。

  实现:

  1) 子类化AsyncTask
  2) 实现AsyncTask中定义的下面一个或几个方法
onPreExecute() 开始执行前的准备工作;
doInBackground(Params...) 开始执行后台处理,可以调用publishProgress方法来更新实时的任务进度;
onProgressUpdate(Progress...) 在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
onPostExecute(Result) 执行完成后的操作,传送结果给UI 线程。

  注意: 1) AsyncTask的实例必须在UI thread中创建;
2) AsyncTask.execute方法必须在UI thread中调用;

  3)该task只能被执行一次,否则多次调用时将会出现异常。而且是不能手动停止

下面是一个例子,AsyncTask_eoe

  1. packagexiaohang.zhimeng;
  2. importandroid.app.Activity;
  3. importandroid.os.AsyncTask;
  4. importandroid.os.Bundle;
  5. importandroid.os.Handler;
  6. importandroid.os.Message;
  7. importandroid.os.SystemClock;
  8. importandroid.widget.TextView;
  9. importandroid.widget.Toast;
  10. /**
  11. *一个使用异步任务的例子。一般来说一个异步任务只执行一次,这个例子有点非主流,任务结束后会触发下一次任务执行。
  12. *由任务task在屏幕上打印数字,第一次任务执行由主Activity的onCreate触发,每次任务结束后
  13. *设定下一次触发的时间,共执行5次。对于任务来说doInBackground()接收任务的参数params,并执行产生数字的动作,每一个数字
  14. *产生后调用一次publishProgress()来更新UI,这个函数本身也是异步的只是用来发个消息调用完成后立即返回,
  15. *而产生数字的动作在继续进行。更新界面的操作在onProgressUpdate()中设定。所有的on函数都由系统调用,不能用户调用。
  16. *代码中使用Handler是为了能触发任务执行,android规定这种异步任务每次执行完就结束,若要重新执行需要new一个新的。
  17. *异步任务只能在UI线程里面创建和执行
  18. */
  19. publicclasstestAsyncextendsActivity{
  20. privatefinalintMSG_TIMER=10000;
  21. privateTextViewvText=null;
  22. @Override
  23. protectedvoidonCreate(BundlesavedInstanceState){
  24. //TODOAuto-generatedmethodstub
  25. super.onCreate(savedInstanceState);
  26. setContentView(R.layout.test);
  27. vText=(TextView)findViewById(R.id.TextView01);
  28. vText.setText("Num...");
  29. newtask().execute("->");
  30. }
  31. //接收任务task发来的消息,触发一个新的任务
  32. privatefinalHandlerhandler=newHandler(){
  33. @Override
  34. publicvoidhandleMessage(Messagemsg){
  35. //TODOAuto-generatedmethodstub
  36. super.handleMessage(msg);
  37. System.out.println("Handlername----------->"+Thread.currentThread().getName());
  38. System.out.println("Handlerid------------>"+Thread.currentThread().getId());
  39. switch(msg.what){
  40. caseMSG_TIMER:
  41. newtask().execute("->");
  42. break;
  43. }
  44. }
  45. };
  46. //任务执行次数
  47. privatestaticinttimes=1;
  48. //AsyncTask<>的参数类型由用户设定,这里设为三个String
  49. //第一个String代表输入到任务的参数类型,也即是doInBackground()的参数类型
  50. //第二个String代表处理过程中的参数类型,也就是doInBackground()执行过程中的产出参数类型,通过publishProgress()发消息
  51. //传递给onProgressUpdate()一般用来更新界面
  52. //第三个String代表任务结束的产出类型,也就是doInBackground()的返回值类型,和onPostExecute()的参数类型
  53. privateclasstaskextendsAsyncTask<String,String,String>{
  54. //后台执行的耗时任务,接收参数并返回结果
  55. //当onPostExecute()执行完,在后台线程中被系统调用
  56. @Override
  57. protectedStringdoInBackground(String...params){
  58. System.out.println("doInBackgroundname----->"+Thread.currentThread().getName());
  59. System.out.println("doInBackgroundid----->"+Thread.currentThread().getId());
  60. //TODOAuto-generatedmethodstub
  61. //在这里产生数据,送给onProgressUpdate以更新界面
  62. Stringpre=params[0];
  63. System.out.println("preis----->"+pre);
  64. for(inti=0;i<5;i++){
  65. System.out.println("noteiambeginsleep");
  66. publishProgress(pre+i);
  67. //这里是否需要停顿下
  68. System.out.println("hualidebuzhuo"+pre+i);
  69. SystemClock.sleep(1000);
  70. }
  71. return"任务结束";
  72. }
  73. //任务执行结束后,在UI线程中被系统调用
  74. //一般用来显示任务已经执行结束
  75. @Override
  76. protectedvoidonPostExecute(Stringresult){
  77. //TODOAuto-generatedmethodstub
  78. System.out.println("onPostExecutename-------->"+Thread.currentThread().getName());
  79. System.out.println("onPostExecuteid-------->"+Thread.currentThread().getName());
  80. super.onPostExecute(result);
  81. Toast.makeText(testAsync.this,result,Toast.LENGTH_SHORT).show();
  82. //任务执行5次后推出
  83. if(times>5){
  84. return;
  85. }
  86. //设定下一次任务触发时间
  87. Messagemsg=Message.obtain();
  88. msg.what=MSG_TIMER;
  89. handler.sendMessageDelayed(msg,10000L);
  90. }
  91. //最先执行,在UI线程中被系统调用
  92. //一般用来在UI中产生一个进度条
  93. @Override
  94. protectedvoidonPreExecute(){
  95. //TODOAuto-generatedmethodstub
  96. System.out.println("onPreExecuteid------->"+Thread.currentThread().getId());
  97. System.out.println("onPreExecutename------->"+Thread.currentThread().getName());
  98. super.onPreExecute();
  99. Toast.makeText(testAsync.this,"开始执行第"+times+"次任务:"+this,
  100. Toast.LENGTH_SHORT).show();
  101. times++;
  102. }
  103. //更新界面操作,在收到更新消息后,在UI线程中被系统调用
  104. @Override
  105. protectedvoidonProgressUpdate(String...values){
  106. //TODOAuto-generatedmethodstub
  107. System.out.println("onProgressUpdateid--------->"+Thread.currentThread().getId());
  108. System.out.println("onProgressUpdatename------->"+Thread.currentThread().getName());
  109. super.onProgressUpdate(values);
  110. vText.append(values[0]);
  111. }
  112. }
  113. }

这个例子,写得很好,里面写了很多关于它的一些使用的方法,注意在使用execute(XXX)里面的参数,就是对应到下面几个方法里面的参数,AsyncTask<Params, Progress, Result>,这个就是相应的映射的参数表。


更多相关文章

  1. [置顶] [Android基础]Android的消息机制
  2. Android消息机制源码解析(一)——消息的载体Message
  3. Android 消息推送(二)基于 MQTT 协议实现的推送功能
  4. Android异步消息机制Handler详解,源码剖析(API 23)
  5. Android 线程完全解析
  6. 主线程中Looper的轮询死循环为何没有阻塞主线程?

随机推荐

  1. join()方法的神奇用处与Intern机制的软肋
  2. [译]PEP 342--增强型生成器:协程
  3. Python进阶:设计模式之迭代器模式
  4. Python 之父退位后,最高决策权花落谁家?
  5. 简单配置nginx反向代理服务
  6. excel 中设置下拉菜单,让其一直显示
  7. 这件正在发生的事,关乎所有的Python开发者
  8. python入门教程12-06 (python语法入门之进
  9. 如何使用visual studio 2017
  10. 最新进展|关于Python治理模式的投票