首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

Activity中运用线程的例子

2013-04-12 
Activity中使用线程的例子转自:http://blog.csdn.net/yihui823/article/details/6741411?今天看到一段很糟

Activity中使用线程的例子

转自:http://blog.csdn.net/yihui823/article/details/6741411

?

今天看到一段很糟糕的代码。于是做了一个工程,模拟这段代码,向大家说明一下线程在使用中要注意的几点。这个例子适合给新手,也欢迎各位高手来指点一下。

首先,上代码。

第一个类LoginService,这是一个模拟类,把业务剥离出去了。只是模拟登录操作而已。

?

?

[java]?view plaincopy
  1. package?com.study;??
  2. package?com.study;??
  3. ??
  4. /**?
  5. ?*?虚拟的一个登录服务.?
  6. ?*?@author?yihui823?
  7. ?*/??
  8. public?class?LoginService?{??
  9. ??
  10. ????//单例??
  11. ????private?static?LoginService?oneInstance?=?new?LoginService();??
  12. ??????
  13. ????/**?
  14. ?????*?得到唯一的一个单例?
  15. ?????*?@return?唯一的一个单例?
  16. ?????*/??
  17. ????public?static?LoginService?getInstance()?{??
  18. ????????return?oneInstance;??
  19. ????}??
  20. ??????
  21. ????//登录成功标记??
  22. ????private?boolean?hadLogin?=?false;??
  23. ??????
  24. ????/**?
  25. ?????*?模拟登录操作?
  26. ?????*?@return?true:登录成功?
  27. ?????*/??
  28. ????public?boolean?login()?{??
  29. ????????try?{??
  30. ????????????Thread.sleep(2000);??
  31. ????????}?catch?(InterruptedException?e)?{??
  32. ????????}??
  33. ????????hadLogin?=?true;??
  34. ????????return?hadLogin;??
  35. ????}??
  36. ??????
  37. ????/**?
  38. ?????*?判断是否登录?
  39. ?????*?@return?true:已经登录?
  40. ?????*/??
  41. ????public?boolean?isLogin()?{??
  42. ????????return?hadLogin;??
  43. ????}??
  44. }??


第二个类就是我们的Activity了。

?

?

?

[java]?view plaincopy
  1. package?com.study;??
  2. ??
  3. import?android.app.Activity;??
  4. import?android.os.Bundle;??
  5. import?android.widget.Toast;??
  6. ??
  7. /**?
  8. ?*?一个段不好的代码?
  9. ?*?@author?yihui823?
  10. ?*/??
  11. public?class?BadCodeActivity?extends?Activity?{??
  12. ??????
  13. ????//登录服务??
  14. ????private?LoginService?lService?=?LoginService.getInstance();??
  15. ??????
  16. ????/**?Called?when?the?activity?is?first?created.?*/??
  17. ????@Override??
  18. ????public?void?onCreate(Bundle?savedInstanceState)?{??
  19. ????????super.onCreate(savedInstanceState);??
  20. ????????setContentView(R.layout.main);??
  21. ??
  22. ????????new?Thread(new?Runnable()?{??
  23. ????????????@Override??
  24. ????????????public?void?run()?{??
  25. ????????????????while(!lService.isLogin()?)?{??
  26. ????????????????????try?{??
  27. ????????????????????????lService.login();??
  28. ????????????????????????Thread.sleep(1000);??
  29. ????????????????????}?catch?(InterruptedException?e)?{??
  30. ????????????????????????e.printStackTrace();??
  31. ????????????????????}??
  32. ????????????????}??
  33. ????????????????Toast.makeText(BadCodeActivity.this,?"登录成功",?Toast.LENGTH_LONG).show();??
  34. ????????????}??
  35. ????????}).start();??
  36. ????}??
  37. }??

?

[java]?view plaincopy
  1. <span?style="background-color:?rgb(255,?255,?255);">这个例子呢,显然运行的时候会报错的。请见我的另一篇文章:<a?href="http://blog.csdn.net/yihui823/article/details/6722784"?target="_blank">Android画面UI中的线程约束</a>。我们在非UI线程里去控制UI界面,就必须使用Handler来发送消息。修改代码如下:</span>??

?

?

?

[java]?view plaincopy
  1. package?com.study;??
  2. ??
  3. import?android.app.Activity;??
  4. import?android.os.Bundle;??
  5. import?android.os.Handler;??
  6. import?android.os.Message;??
  7. import?android.widget.Toast;??
  8. ??
  9. /**?
  10. ?*?一个段不好的代码?
  11. ?*?@author?yihui823?
  12. ?*/??
  13. public?class?BadCodeActivity?extends?Activity?{??
  14. ??????
  15. ????//登录服务??
  16. ????private?LoginService?lService?=?LoginService.getInstance();??
  17. ??????
  18. ????<span?style="color:#ff6666;">//外线程访问UI线程的Handle??
  19. ????private?Handler?mhandle?=?new?Handler(){??
  20. ????????@Override??
  21. ????????public?void?handleMessage(Message?msg)?{??
  22. ????????????Toast.makeText(BadCodeActivity.this,?"登录成功",?Toast.LENGTH_LONG).show();??
  23. ????????}??
  24. ????};</span>??
  25. ??????
  26. ??????
  27. ????/**?Called?when?the?activity?is?first?created.?*/??
  28. ????@Override??
  29. ????public?void?onCreate(Bundle?savedInstanceState)?{??
  30. ????????super.onCreate(savedInstanceState);??
  31. ????????setContentView(R.layout.main);??
  32. ??
  33. ????????new?Thread(new?Runnable()?{??
  34. ????????????@Override??
  35. ????????????public?void?run()?{??
  36. ????????????????while(!lService.isLogin()?)?{??
  37. ????????????????????try?{??
  38. ????????????????????????lService.login();??
  39. ????????????????????????Thread.sleep(1000);??
  40. ????????????????????}?catch?(InterruptedException?e)?{??
  41. ????????????????????????e.printStackTrace();??
  42. ????????????????????}??
  43. ????????????????}??
  44. ????????????????<span?style="color:#ff0000;">mhandle.sendEmptyMessage(0);</span>??
  45. ????????????}??
  46. ????????}).start();??
  47. ????}??
  48. }??

?

[java]?view plaincopy
  1. <p><span?style="background-color:?rgb(255,?255,?255);">红色部分代码,就是修改的地方。现在,这段代码可以运行了,而且还貌似不错,是吧。</span></p><p><span?style="background-color:?rgb(255,?255,?255);">但是,一个好的程序,不能只是应付正常情况,还要应付错误情况,是吧。如果登录总是出错怎么样呢?我们把LoginService类略微改动,如下:</span></p>??

?

?

?

[java]?view plaincopy
  1. package?com.study;??
  2. ??
  3. import?android.util.Log;??
  4. ??
  5. /**?
  6. ?*?虚拟的一个登录服务.?
  7. ?*?@author?yihui823?
  8. ?*/??
  9. public?class?LoginService?{??
  10. ??
  11. ????private?static?final?String?TAG?=?"LoginService";??
  12. ??????
  13. ????//单例??
  14. ????private?static?LoginService?oneInstance?=?new?LoginService();??
  15. ??????
  16. ????/**?
  17. ?????*?得到唯一的一个单例?
  18. ?????*?@return?唯一的一个单例?
  19. ?????*/??
  20. ????public?static?LoginService?getInstance()?{??
  21. ????????return?oneInstance;??
  22. ????}??
  23. ??????
  24. ????//登录成功标记??
  25. ????private?boolean?hadLogin?=?false;??
  26. ??????
  27. ????/**?
  28. ?????*?模拟登录操作?
  29. ?????*?@return?true:登录成功?
  30. ?????*/??
  31. ????public?boolean?login()?{??
  32. ????????try?{??
  33. ????????????Thread.sleep(2000);??
  34. ????????}?catch?(InterruptedException?e)?{??
  35. ????????}??
  36. ????????Log.d(TAG,?"we?are?login");??
  37. //??????hadLogin?=?true;??
  38. ??????????
  39. ????????return?hadLogin;??
  40. ????}??
  41. ??????
  42. ????/**?
  43. ?????*?判断是否登录?
  44. ?????*?@return?true:已经登录?
  45. ?????*/??
  46. ????public?boolean?isLogin()?{??
  47. ????????return?hadLogin;??
  48. ????}??
  49. }??


增加了Log,以便查看登录情况。模拟业务代码只改了一行,就是登录永远是失败。现在运行一下呢。停在页面上没有动静了,logcat里也不断的打出:
we are login
这个也不会有什么错误,对吧。但是,我们如果按“返回”键退出页面,再看看logcat呢?
we are login的log还在不停的输出,是吗?
我想现在大家应该知道哪里出了问题了。就是说,我们的线程启动之后,就没法停掉了。
这里我要说一下。我一直认为,
new Thread(new Runnable() {…}().start();
这种代码写的非常的不好。你直接构造了一个对象,但是这个对象你没有任何的变量去指向它。这个线程被你启动之后,你已经无法再去跟踪、调用、管理了。这个线程,只能自生自灭,永远游离在你的控制范围之外。你会不会觉得,这个线程跟僵尸一样?对,这就是僵尸进程,如果它没有停止的条件,就永远在你的系统里消耗你的资源。
所以我觉得使用线程的一个基本认识:生成的线程类,一定要有一个变量去指向它,以便在合适的时候销毁。
这里说到销毁,这就是另一个问题了。Thread类已经废弃了stop方法了,因为线程需要自行去释放该释放的资源,不能光依赖于运行框架的控制。我们需要在Thread里面,加上他自己停止的代码。也就是说,不论如何,线程应该会自己去停止掉,而不应该是无限制的运行。
另外,我们在Android里面,还应该注意Activity的各个状态周转。一般来说,线程的启动在onCreate里是不合适的,我们必须考虑到onResume和onPause的情况。
那么,我们总结下,Activity里使用线程有三个注意:
1, 线程对象一定要有变量指向它,以便我们可以控制。
2, 线程类一定要有停止条件,以便外界通知线程自行停止。
3, 在onResume里启动线程,在onPause里停止线程

我们根据以上三点,重新写一下Activity。

?

?

?

[java]?view plaincopy
  1. package?com.study;??
  2. ??
  3. import?android.app.Activity;??
  4. import?android.os.Bundle;??
  5. import?android.os.Handler;??
  6. import?android.os.Message;??
  7. import?android.util.Log;??
  8. import?android.widget.Toast;??
  9. ??
  10. /**?
  11. ?*?一个段不好的代码?
  12. ?*?@author?yihui823?
  13. ?*/??
  14. public?class?BadCodeActivity?extends?Activity?{??
  15. ??
  16. ????private?static?final?String?TAG?=?"BadCodeActivity";??
  17. ??????
  18. ????//登录服务??
  19. ????private?LoginService?lService?=?LoginService.getInstance();??
  20. ??????
  21. ????//外线程访问UI线程的Handle??
  22. ????private?Handler?mhandle?=?new?Handler(){??
  23. ????????@Override??
  24. ????????public?void?handleMessage(Message?msg)?{??
  25. ????????????Toast.makeText(BadCodeActivity.this,?"登录成功",?Toast.LENGTH_LONG).show();??
  26. ????????}??
  27. ????};??
  28. ??????
  29. ????//通知停止线程的标记??
  30. ????private?boolean?stopFlag?=?false;??
  31. ??????
  32. ????//登录成功标记??
  33. ????private?boolean?loginOk?=?false;??
  34. ??????
  35. ????/**?
  36. ?????*?登录用的线程类?
  37. ?????*/??
  38. ????private?class?LoginThread?extends?Thread?{??
  39. ??????????
  40. ????????@Override??
  41. ????????public?void?run()?{??
  42. ????????????while(!stopFlag)?{??
  43. ????????????????loginOk?=?lService.isLogin();??
  44. ????????????????if?(loginOk)?{??
  45. ????????????????????break;??
  46. ????????????????}??
  47. ????????????????try?{??
  48. ????????????????????lService.login();??
  49. ????????????????????Thread.sleep(1000);??
  50. ????????????????}?catch?(InterruptedException?e)?{??
  51. ????????????????????e.printStackTrace();??
  52. ????????????????}??
  53. ????????????}??
  54. ????????????mhandle.sendEmptyMessage(0);??
  55. ????????}??
  56. ??????????
  57. ????????/**?
  58. ?????????*?通知线程需要停止?
  59. ?????????*/??
  60. ????????public?void?stopLogin()?{??
  61. ????????????stopFlag?=?true;??
  62. ????????}??
  63. ????};??
  64. ??
  65. ????//用来登录的线程??
  66. ????private?LoginThread?loginThread?=?new?LoginThread();??
  67. ??????
  68. ??????
  69. ????/**?Called?when?the?activity?is?first?created.?*/??
  70. ????@Override??
  71. ????public?void?onCreate(Bundle?savedInstanceState)?{??
  72. ????????super.onCreate(savedInstanceState);??
  73. ????????setContentView(R.layout.main);??
  74. ????????Log.d(TAG,?"BadCodeActivity?instance?is?called?onCreate?:"?+?this.hashCode());??
  75. ????}??
  76. ??????
  77. ????public?void?onResume()?{??
  78. ????????super.onResume();??
  79. ????????Log.d(TAG,?"BadCodeActivity?instance?is?called?onResume?:"?+?this.hashCode());??
  80. ????????loginThread.start();??
  81. ????}??
  82. ??????
  83. ????public?void?onPause()?{??
  84. ????????super.onPause();??
  85. ????????loginThread.stopLogin();??
  86. ????}??
  87. }??


现在,我们的线程可以在页面退出的时候正常停止了。
?
但是这段代码还是有问题的。我们仔细看看,线程在Activity构造的时候就已经创建了,然后在程序进到前台的时候启动,退到后台的时候停止。但是线程有这么一个特性:
一旦线程的run()函数运行结束了,这个线程就销毁了,不能再启动了。
现在我们的程序,在退出后将不可能再次显示,所以系统会马上回收掉Activity。如果我们的页面增加一个按钮,迁移到另一个页面,那么在那个页面返回的时候,就会有异常出现。我们修改一下代码来试试。
增加一个Activity:

?

?

[java]?view plaincopy
  1. package?com.study;??
  2. ??
  3. import?android.app.Activity;??
  4. import?android.os.Bundle;??
  5. ??
  6. /**?
  7. ?*?临时页面?
  8. ?*?@author?yihui823?
  9. ?*/??
  10. public?class?TempActivity?extends?Activity?{??
  11. ??
  12. ????/**?Called?when?the?activity?is?first?created.?*/??
  13. ????@Override??
  14. ????public?void?onCreate(Bundle?savedInstanceState)?{??
  15. ????????super.onCreate(savedInstanceState);??
  16. ????????setContentView(R.layout.main);??
  17. ????}??
  18. }??



?

[java]?view plaincopy
  1. <pre?class="java"?name="code"></pre>??
  2. <p>别忘了修改AndroidManifest.xml,增加Activity的说明:</p>??
  3. <p?align="left">?????????<activity?android:name=".TempActivity"<br>??
  4. ??????????????????android:label="@string/app_name"/><br>??
  5. </p>??
  6. <p?align="left">修改BadCodeActivity:</p>??
  7. <p><br>??
  8. </p>??
  9. <pre?class="java"?name="code">package?com.study;??
  10. ??
  11. import?android.app.Activity;??
  12. import?android.content.Intent;??
  13. import?android.os.Bundle;??
  14. import?android.os.Handler;??
  15. import?android.os.Message;??
  16. import?android.util.Log;??
  17. import?android.view.View;??
  18. import?android.view.View.OnClickListener;??
  19. import?android.widget.Button;??
  20. import?android.widget.Toast;??
  21. ??
  22. /**?
  23. ?*?一个段不好的代码?
  24. ?*?@author?yihui823?
  25. ?*/??
  26. public?class?BadCodeActivity?extends?Activity?{??
  27. ??
  28. ????private?static?final?String?TAG?=?"BadCodeActivity";??
  29. ??????
  30. ????//登录服务??
  31. ????private?LoginService?lService?=?LoginService.getInstance();??
  32. ??????
  33. ????//外线程访问UI线程的Handle??
  34. ????private?Handler?mhandle?=?new?Handler(){??
  35. ????????@Override??
  36. ????????public?void?handleMessage(Message?msg)?{??
  37. ????????????Toast.makeText(BadCodeActivity.this,?"登录成功",?Toast.LENGTH_LONG).show();??
  38. ????????}??
  39. ????};??
  40. ??????
  41. ????//通知停止线程的标记??
  42. ????private?boolean?stopFlag?=?false;??
  43. ??????
  44. ????//登录成功标记??
  45. ????private?boolean?loginOk?=?false;??
  46. ??????
  47. ????/**?
  48. ?????*?登录用的线程类?
  49. ?????*/??
  50. ????private?class?LoginThread?extends?Thread?{??
  51. ??????????
  52. ????????@Override??
  53. ????????public?void?run()?{??
  54. ????????????while(!stopFlag)?{??
  55. ????????????????loginOk?=?lService.isLogin();??
  56. ????????????????if?(loginOk)?{??
  57. ????????????????????break;??
  58. ????????????????}??
  59. ????????????????try?{??
  60. ????????????????????lService.login();??
  61. ????????????????????Thread.sleep(1000);??
  62. ????????????????}?catch?(InterruptedException?e)?{??
  63. ????????????????????e.printStackTrace();??
  64. ????????????????}??
  65. ????????????}??
  66. ????????????mhandle.sendEmptyMessage(0);??
  67. ????????}??
  68. ??????????
  69. ????????/**?
  70. ?????????*?通知线程需要停止?
  71. ?????????*/??
  72. ????????public?void?stopLogin()?{??
  73. ????????????stopFlag?=?true;??
  74. ????????}??
  75. ????};??
  76. ??
  77. ????//用来登录的线程??
  78. ????private?LoginThread?loginThread?=?new?LoginThread();??
  79. ??????
  80. ??????
  81. ????/**?Called?when?the?activity?is?first?created.?*/??
  82. ????@Override??
  83. ????public?void?onCreate(Bundle?savedInstanceState)?{??
  84. ????????super.onCreate(savedInstanceState);??
  85. ????????setContentView(R.layout.main);??
  86. ??????????
  87. ?<span?style="color:#ff0000;">???????Button?btn?=?(Button)findViewById(R.id.btn);??
  88. ????????btn.setOnClickListener(new?OnClickListener()?{??
  89. ????????????@Override??
  90. ????????????public?void?onClick(View?arg0)?{??
  91. ????????????????startActivity(new?Intent(BadCodeActivity.this,TempActivity.class));??
  92. ????????????}??
  93. ????????});</span>??
  94. ??????????
  95. ????????Log.d(TAG,?"BadCodeActivity?instance?is?called?onCreate?:"?+?this.hashCode());??
  96. ????}??
  97. ??????
  98. ????public?void?onResume()?{??
  99. ????????super.onResume();??
  100. ????????Log.d(TAG,?"BadCodeActivity?instance?is?called?onResume?:"?+?this.hashCode());??
  101. ????????loginThread.start();??
  102. ????}??
  103. ??????
  104. ????public?void?onPause()?{??
  105. ????????super.onPause();??
  106. ????????loginThread.stopLogin();??
  107. ????}??
  108. }??
  109. </pre>??
  110. <p><br>??
  111. </p>??
  112. <p?align="left">?</p>??
  113. <p>其实就是加了一个按钮,做一个页面迁移。别忘了在main.xml里面加上:</p>??
  114. <pre?class="html"?name="code"><Button??
  115. ????android:id="@+id/btn"????
  116. ????android:layout_width="fill_parent"???
  117. ????android:layout_height="wrap_content"???
  118. ????android:text="@string/hello"??
  119. ????/>??
  120. </pre>??
  121. <p><br>??
  122. ?</p>??
  123. <p>现在我们运行程序。运行之后,点击按钮,画面闪动一下说明是切换了页面。我们偷了个懒,两个Activity共用一个layout,所以页面没有任何变化。但是没关系,我们看log,we?are?login已经停止输出了。这个时候,我们再按返回键,应该是切换回BadCodeActivity。这个时候系统报错:</p>??
  124. <p>java.lang.IllegalThreadStateException:?Thread?already?started.</p>??
  125. <p>显然,就是说线程已经启动过了,不能再次被利用。</p>??
  126. <p>我们对代码需要做一点点修改。当然,我们也顺手改掉一个BUG:在退出的时候还会报告登录成功。</p>??
  127. <p>并且,我们把控制变量都放在内部类里,做到变量最小化生存空间。</p>??
  128. <p>修改后如下:</p>??
  129. <pre?class="java"?name="code">package?com.study;??
  130. ??
  131. import?android.app.Activity;??
  132. import?android.content.Intent;??
  133. import?android.os.Bundle;??
  134. import?android.os.Handler;??
  135. import?android.os.Message;??
  136. import?android.util.Log;??
  137. import?android.view.View;??
  138. import?android.view.View.OnClickListener;??
  139. import?android.widget.Button;??
  140. import?android.widget.Toast;??
  141. ??
  142. /**?
  143. ?*?一个段不好的代码?
  144. ?*?@author?yihui823?
  145. ?*/??
  146. public?class?BadCodeActivity?extends?Activity?{??
  147. ??
  148. ????private?static?final?String?TAG?=?"BadCodeActivity";??
  149. ??????
  150. ????//登录服务??
  151. ????private?LoginService?lService?=?LoginService.getInstance();??
  152. ??????
  153. ????//外线程访问UI线程的Handle??
  154. ????private?Handler?mhandle?=?new?Handler(){??
  155. ????????@Override??
  156. ????????public?void?handleMessage(Message?msg)?{??
  157. ????????????Toast.makeText(BadCodeActivity.this,?"登录成功",?Toast.LENGTH_LONG).show();??
  158. ????????}??
  159. ????};??
  160. ??????
  161. ????/**?
  162. ?????*?登录用的线程类?
  163. ?????*/??
  164. ????private?class?LoginThread?extends?Thread?{??
  165. ??
  166. ????????//通知停止线程的标记??
  167. ????????private?boolean?stopFlag?=?false;??
  168. ??????????
  169. ????????//登录成功标记??
  170. ????????private?boolean?loginOk?=?false;??
  171. ??????????
  172. ????????@Override??
  173. ????????public?void?run()?{??
  174. ????????????while(!stopFlag)?{??
  175. ????????????????loginOk?=?lService.isLogin();??
  176. ????????????????if?(loginOk)?{??
  177. ????????????????????break;??
  178. ????????????????}??
  179. ????????????????try?{??
  180. ????????????????????lService.login();??
  181. ????????????????????Thread.sleep(1000);??
  182. ????????????????}?catch?(InterruptedException?e)?{??
  183. ????????????????????e.printStackTrace();??
  184. ????????????????}??
  185. ????????????}??
  186. ????????????if?(loginOk)?{??
  187. ????????????????mhandle.sendEmptyMessage(0);??
  188. ????????????}??
  189. ????????}??
  190. ??????????
  191. ????????/**?
  192. ?????????*?通知线程需要停止?
  193. ?????????*/??
  194. ????????public?void?stopLogin()?{??
  195. ????????????stopFlag?=?true;??
  196. ????????}??
  197. ????};??
  198. ??
  199. ????//用来登录的线程??
  200. ????private?LoginThread?loginThread;??
  201. ??????
  202. ??????
  203. ????/**?Called?when?the?activity?is?first?created.?*/??
  204. ????@Override??
  205. ????public?void?onCreate(Bundle?savedInstanceState)?{??
  206. ????????super.onCreate(savedInstanceState);??
  207. ????????setContentView(R.layout.main);??
  208. ??????????
  209. ????????Button?btn?=?(Button)findViewById(R.id.btn);??
  210. ????????btn.setOnClickListener(new?OnClickListener()?{??
  211. ????????????@Override??
  212. ????????????public?void?onClick(View?arg0)?{??
  213. ????????????????startActivity(new?Intent(BadCodeActivity.this,TempActivity.class));??
  214. ????????????}??
  215. ????????});??
  216. ??????????
  217. ????????Log.d(TAG,?"BadCodeActivity?instance?is?called?onCreate?:"?+?this.hashCode());??
  218. ????}??
  219. ??????
  220. ????public?void?onResume()?{??
  221. ????????super.onResume();??
  222. ????????Log.d(TAG,?"BadCodeActivity?instance?is?called?onResume?:"?+?this.hashCode());??
  223. ????????<span?style="color:#ff0000;">loginThread?=?new?LoginThread();</span>??
  224. ????????loginThread.start();??
  225. ????}??
  226. ??????
  227. ????public?void?onPause()?{??
  228. ????????super.onPause();??
  229. ????????loginThread.stopLogin();??
  230. ????}??
  231. }??
  232. ??
  233. </pre>??
  234. <p?align="left"><br>??
  235. ?</p>??
  236. <p>现在,我们点击按钮,进入到TempActivity的时候,登录log停止输出;然后按返回键,回到BadCodeActivity的时候,登录log又继续输出。程序基本完成,没有僵尸线程存在了。红色的那行代码是关键!</p>??
  237. <p>我们总结一下:</p>??
  238. <p><strong>1,?线程对象一定要有变量指向它,以便我们可以控制。</strong></p>??
  239. <p><strong>2,?线程类一定要有停止条件,以便外界通知线程自行停止。</strong></p>??
  240. <p><strong>3,?线程启动之后,不管是不是已经停止了,都是不能再次利用的。</strong></p>??
  241. <p>4,??<strong>在onResume里新建和启动线程,在onPause里停止线程。</strong></p>??
  242. <p>?</p>??
  243. <p>?</p>??
  244. <pre></pre>??
  245. <pre></pre>??
  246. <pre></pre>??
  247. <pre></pre> ?

热点排行