理解线程

作者:追风剑情 发布于:2015-8-3 23:06 分类:Android

以下为一个计数器示例,通过这个示例来理解线程。

视图

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical"
  6. tools:context="${relativePackage}.${activityClass}" >
  7.  
  8.  
  9. <Button
  10. android:id="@+id/btnStartCounter"
  11. android:layout_width="match_parent"
  12. android:layout_height="wrap_content"
  13. android:text="Start"
  14. android:onClick="startCounter5" />
  15. <TextView
  16. android:id="@+id/textView1"
  17. android:layout_width="match_parent"
  18. android:layout_height="wrap_content"
  19. android:text="TextView" />
  20.  
  21. </LinearLayout>

活动

  1. package com.example.androidtest;
  2.  
  3. import android.app.Activity;
  4. import android.os.AsyncTask;
  5. import android.os.Bundle;
  6. import android.os.Handler;
  7. import android.os.Message;
  8. import android.util.Log;
  9. import android.view.Menu;
  10. import android.view.MenuItem;
  11. import android.view.View;
  12. import android.widget.TextView;
  13.  
  14. public class ThreadingActivity extends Activity {
  15.  
  16. static TextView txtView1;
  17. DoCountingTask task;
  18. @Override
  19. protected void onCreate(Bundle savedInstanceState) {
  20. super.onCreate(savedInstanceState);
  21. setContentView(R.layout.activity_threading);
  22. txtView1 = (TextView) findViewById(R.id.textView1);
  23. }
  24. @Override
  25. protected void onPause(){
  26. super.onPause();
  27. stopCounter(txtView1);
  28. }
  29. /**
  30. * 方案一
  31. * 此方案会使UI无响应。
  32. * @param view
  33. */
  34. public void startCounter1(View view){
  35. for(int i=0; i<=1000; i++){
  36. txtView1.setText(String.valueOf(i));
  37. try {
  38. Thread.sleep(1000);//UI线程中执行
  39. } catch (InterruptedException e) {
  40. Log.d("AndroidTest", e.getLocalizedMessage());
  41. }
  42. }
  43. }
  44. /**
  45. * 方案二
  46. * 此方案会使程序崩溃。
  47. * @param view
  48. */
  49. public void startCounter2(View view){
  50. new Thread(new Runnable(){
  51. @Override
  52. public void run() {//工作者线程
  53. for(int i=0; i<=1000; i++){
  54. //在工作者线程中更新UI,会导致程序崩溃。
  55. txtView1.setText(String.valueOf(i));//这句会使程序崩溃
  56. try {
  57. Thread.sleep(1000);
  58. } catch (InterruptedException e) {
  59. Log.d("AndroidTest", e.getLocalizedMessage());
  60. }
  61. }
  62. }
  63. }).start();
  64. }
  65. /**
  66. * 方案三
  67. * 此方案可行,但是代码十分复杂,不易维护。
  68. * @param view
  69. */
  70. public void startCounter3(View view){
  71. new Thread(new Runnable(){
  72. @Override
  73. public void run() {//工作者线程
  74. for(int i=0; i<=1000; i++){
  75. final int valueOfi = i;
  76. txtView1.post(new Runnable(){//UI线程
  77. public void run(){
  78. txtView1.setText(String.valueOf(valueOfi));
  79. }
  80. });
  81. //---插入一个延迟
  82. try {
  83. Thread.sleep(1000);
  84. } catch (InterruptedException e) {
  85. Log.d("AndroidTest", e.getLocalizedMessage());
  86. }
  87. }
  88. }
  89. }).start();
  90. }
  91. /**
  92. * 方案四
  93. * 此方案可行。利用Handler类。
  94. * @param view
  95. */
  96. public void startCounter4(View view){
  97. new Thread(new Runnable(){
  98. @Override
  99. public void run() {//工作者线程
  100. for(int i=0; i<=1000; i++){
  101. ThreadingActivity.UIupdater.obtainMessage(0, String.valueOf(i).getBytes()).sendToTarget();
  102. try {
  103. Thread.sleep(1000);
  104. } catch (InterruptedException e) {
  105. Log.d("AndroidTest", e.getLocalizedMessage());
  106. }
  107. }
  108. }
  109. }).start();
  110. }
  111. /**
  112. * 方案五
  113. * 此为推荐方案。
  114. * @param view
  115. */
  116. public void startCounter5(View view){
  117. task = (DoCountingTask) new DoCountingTask().execute();
  118. }
  119. /**
  120. * 取消任务
  121. * 如果不调用任务的cancel()方法,就算活动销毁了(比如用户按了black键),任务还是会继续执行。
  122. * @param view
  123. */
  124. public void stopCounter(View view){
  125. if(null != task)
  126. task.cancel(true);
  127. }
  128. static Handler UIupdater = new Handler(){
  129. @Override
  130. public void handleMessage(Message msg){
  131. byte[] buffer = (byte[]) msg.obj;
  132. String strReceived = new String(buffer);
  133. txtView1.setText(strReceived);
  134. Log.d("AndroidTest", "running");
  135. }
  136. };
  137. private class DoCountingTask extends AsyncTask<Void, Integer, Void> {
  138. @Override
  139. protected Void doInBackground(Void... params) {
  140. for(int i=0; i<=1000; i++){
  141. publishProgress(i);
  142. try {
  143. Thread.sleep(1000);
  144. } catch (InterruptedException e) {
  145. Log.d("AndroidTest", e.getLocalizedMessage());
  146. }
  147. //检查任务是否该终止
  148. if(isCancelled()) break;
  149. }
  150. return null;
  151. }
  152. protected void onProgressUpdate(Integer... progress){
  153. txtView1.setText(progress[0].toString());
  154. Log.d("AndroidTest", "updating...");
  155. }
  156. }
  157. }

运行效果

111111.png

标签: Android

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号