作者: blogercn (1 篇文章) 日期: 五月 7, 2012 在 6:21 下午
android的應(yīng)用程序支持多線程,多線程編程為我們充分利用系統(tǒng)資源提供了便利,同時(shí)也為設(shè)計(jì)復(fù)雜UI和耗時(shí)操作提供了途徑,提升了安卓用戶的使用體驗(yàn)。Android的多線程和JAVA沒有多大變化,唯一的變化大概在于無法直接使用CANVAS修改屏幕元素,當(dāng)然安卓為我們提供了surfaceview類來實(shí)現(xiàn)多線程中通過畫布canvas修改屏幕。這為設(shè)計(jì)UI和開發(fā)游戲帶來了方便。因此,研究和使用多線程編程,對我們深入學(xué)習(xí)安卓編程有著十分重要的作用。
線程的方法比較多,常用的有:
start();
run();
sleep();
stop();
destroy();
join();
suspend();
resume();
yield(); wait(); notify();
線程啟動一定要使用start方法,線程操作使用run方法,線程休眠使用sleep方法,線程停止使用stop,線程銷毀使用destroy方法,線程同步使用JOIN方法,前面三種最常用,一般來說這三種就可以滿足大部分線程使用需求,run結(jié)束時(shí)線程自動死亡,stop,destroy雖然也能停止線程,但不推薦使用,,前者會產(chǎn)生異常,后者是強(qiáng)制終止,不會釋放鎖,一般會在RUN里設(shè)置一個(gè)狀態(tài)信號來等其自動結(jié)束,這里使用volatile boolean bThreadRun。后面是暫停,繼續(xù),掛起,由于會產(chǎn)生死鎖問題,很少使用。大部分情況會使用wait和notify替代;
這里我使用一個(gè)線程來計(jì)算變量并更新窗口標(biāo)題。主要代碼如下:使用eclipse創(chuàng)建一個(gè)項(xiàng)目。為Activity添加onStart,onPause, onStop等方法,Activity是我們最常使用的一個(gè)類,也是android的核心類,為應(yīng)用程序管理并顯示一個(gè)屏幕,開發(fā)的人不應(yīng)該對其陌生。Activity活動主要的方法有,onCreate,onStart,onStop,onPause,onResume, onRestart,onDestroy,onRestoreInstanceState,onSaveInstanceState,一般的執(zhí)行順序是,onCreate,onStart,onResume,當(dāng)窗口不是最頂層時(shí),執(zhí)行onPause,onstop,為頂層時(shí),執(zhí)行onRestart,onResume,一直循環(huán),直到onDestroy.如果保存窗口,重載onSaveInstanceState,并在進(jìn)入時(shí)重載onRestoreInstanceState。這里我在Activity的方法onStart里創(chuàng)建線程:
01.MyThread myThread = new MyThread(); 02. myThread.start();
在下面添加MyThread的實(shí)現(xiàn)代碼:
01.public class MyThread extends Thread { 02. // 聲明字符串變量 03. public MyThread() { 04. } 05. 06. @Override 07. public void start() { 08. super.start(); 09. } 10. 11. // 線程的主要工作方法 12. @Override 13. public void run() { 14. while (true) { 15. try { 16. sleep(5000); 17. if (c > ((1 << 31) - 1)) { 18. c = 0; 19. } else { 20. c++; 21. } 22. Message message = new Message(); 23. message.what = 1; 24. mHandler.sendMessage(message); 25. } catch (InterruptedException ex) { 26. } 27. } 28. } 29. 30. }
實(shí)現(xiàn)updatetitle方法:
01.public void updateTitle() { 02. setTitle("test thread " + c); 03. }
這里沒有使用updatetitle直接更新窗口,而是使用handler,這是因?yàn)橹苯邮褂檬遣话踩?,會造成線程重啟等問題。Android 引進(jìn)了Handler 這個(gè)特殊的類,用它作為Runnable和Activity交互的橋梁,所以我們只能在run方法中發(fā)送Message,而在Handler里,通過不同的Message執(zhí)行不同的任務(wù)。為程序添加handler;
01.private Handler mHandler = new Handler() { 02. public void handleMessage(Message msg) { 03. switch (msg.what) { 04. case 1: 05. updateTitle(); 06. break; 07. } 08. }; 09. };
最后完整的代碼如下,使用線程處理數(shù)據(jù),并把數(shù)據(jù)顯示在窗口上:
01.package com.test; 02. 03.import android.app.Activity; 04.import android.os.Bundle; 05.import java.lang.Thread; 06.import android.os.Message; 07.import android.os.Handler; 08.import android.graphics.Color; 09. 10.public class TestThreadActivity extends Activity { 11. int c = Color.BLUE; 12. MyThread myThread; 13. volatile boolean bThreadRun = false; 14. 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. } 21. 22. @Override 23. protected void onRestoreInstanceState(android.os.Bundle savedInstanceState) { 24. super.onRestoreInstanceState(savedInstanceState); 25. } 26. 27. @Override 28. protected void onSaveInstanceState(android.os.Bundle outState) { 29. super.onSaveInstanceState(outState); 30. } 31. 32. @Override 33. protected void onStart() { 34. super.onStart(); 35. myThread = new MyThread(); 36. myThread.start(); 37. bThreadRun = true; 38. } 39. 40. @Override 41. protected void onRestart() { 42. super.onRestart(); 43. } 44. 45. @Override 46. protected void onResume() { 47. super.onResume(); 48. } 49. 50. @Override 51. protected void onPause() { 52. super.onPause(); 53. bThreadRun = false; 54. // myThread.stop(); 55. } 56. 57. @Override 58. protected void onStop() { 59. super.onStop(); 60. onPause(); 61. } 62. 63. @Override 64. protected void onDestroy() { 65. super.onDestroy(); 66. // myThread.destroy(); 67. } 68. 69. private Handler mHandler = new Handler() { 70. public void handleMessage(Message msg) { 71. switch (msg.what) { 72. case 1: 73. updateTitle(); 74. break; 75. } 76. }; 77. }; 78. 79. public void updateTitle() { 80. setTitle("test thread " + c); 81. setTitleColor(c); 82. } 83. 84. public class MyThread extends Thread { 85. // 聲明字符串變量 86. public MyThread() { 87. } 88. 89. @Override 90. public void start() { 91. super.start(); 92. } 93. 94. // 線程的主要工作方法 95. @Override 96. public void run() { 97. while (bThreadRun) { 98. try { 99. sleep(100); 100. if (c > ((1 << 16) - 1)) { 101. c = 0; 102. } else { 103. c += 100; 104. } 105. Message message = new Message(); 106. message.what = 1; 107. mHandler.sendMessage(message); 108. } catch (InterruptedException ex) { 109. } 110. } 111. } 112. 113. } 114. 115.}
線程還有另外一種常用的方法是編寫Runnable接口,這里對代碼做一些修改,使用線程實(shí)現(xiàn)對主窗口重繪,全部代碼如下:
01.package com.test; 02. 03.import android.app.Activity; 04.import android.content.Context; 05.import android.os.Bundle; 06.import java.lang.Thread; 07.import android.view.View; 08.import android.graphics.Canvas; 09.import android.graphics.Color; 10.import android.graphics.Paint; 11.import android.graphics.Paint.Style; 12.import android.graphics.Rect; 13. 14.public class TestThreadActivity extends Activity { 15. int c = Color.BLUE; 16. MyThread myThread; 17. volatile boolean bThreadRun = false; 18. MyView mv; 19. 20. /** Called when the activity is first created. */ 21. @Override 22. public void onCreate(Bundle savedInstanceState) { 23. super.onCreate(savedInstanceState); 24. // setContentView(R.layout.main); 25. mv = new MyView(this); 26. setContentView(mv); 27. } 28. 29. public class MyView extends View { 30. MyView(Context context) { 31. super(context); 32. } 33. 34. @Override 35. protected void onDraw(Canvas canvas) { 36. // TODO Auto-generated method stub 37. super.onDraw(canvas); 38. 39. // 首先定義一個(gè)paint 40. Paint paint = new Paint(); 41. 42. // 繪制矩形區(qū)域-實(shí)心矩形 43. // 設(shè)置顏色 44. paint.setColor(c); 45. // 設(shè)置樣式-填充 46. paint.setStyle(Style.FILL); 47. // 繪制一個(gè)矩形 48. canvas.drawRect(new Rect(0, 0, getWidth(), getHeight()), paint); 49. } 50. 51. } 52. 53. @Override 54. protected void onRestoreInstanceState(android.os.Bundle savedInstanceState) { 55. super.onRestoreInstanceState(savedInstanceState); 56. } 57. 58. @Override 59. protected void onSaveInstanceState(android.os.Bundle outState) { 60. super.onSaveInstanceState(outState); 61. } 62. 63. @Override 64. protected void onStart() { 65. super.onStart(); 66. //myThread = new MyThread(); 67. //myThread.start(); 68. new Thread (new MyThread()).start(); 69. bThreadRun = true; 70. } 71. 72. @Override 73. protected void onRestart() { 74. super.onRestart(); 75. } 76. 77. @Override 78. protected void onResume() { 79. super.onResume(); 80. } 81. 82. @Override 83. protected void onPause() { 84. super.onPause(); 85. bThreadRun = false; 86. // myThread.stop(); 87. } 88. 89. @Override 90. protected void onStop() { 91. super.onStop(); 92. onPause(); 93. } 94. 95. @Override 96. protected void onDestroy() { 97. super.onDestroy(); 98. // myThread.destroy(); 99. } 100. 101. public class MyThread implements Runnable{ 102. // 線程的主要工作方法 103. @Override 104. public void run() { 105. while (bThreadRun) { 106. try { 107. Thread.sleep(500); 108. if (c > ((1 << 31) - 1)) { 109. c = 0; 110. } else { 111. c += 100; 112. } 113. mv.postInvalidate(); 114. } catch(InterruptedException e){ 115. } 116. } 117. } 118. 119. } 120. 121.}
|