多線程及消息處理_第1頁
多線程及消息處理_第2頁
多線程及消息處理_第3頁
多線程及消息處理_第4頁
多線程及消息處理_第5頁
已閱讀5頁,還剩32頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、Google Android多線程及消息處理多線程及消息處理on android本章內容本章內容nAndroid多線程概述多線程概述創建線程創建線程操作線程操作線程nUI線程與非線程與非UI線程線程n多線程中的常用類多線程中的常用類Handler類類AsyncTask類類Timer定時器定時器nAndroid多線程通信機制多線程通信機制n使用線程使用線程任何耗時的處理過程都會降低用戶界面的響應速度,甚至導任何耗時的處理過程都會降低用戶界面的響應速度,甚至導致用戶界面失去響應,當用戶界面失去響應超過致用戶界面失去響應,當用戶界面失去響應超過5秒鐘,秒鐘,Android系統會允許用戶強行關閉應用程

2、序系統會允許用戶強行關閉應用程序較好的解決方法是將耗時的處理過程轉移到子線程上,這樣較好的解決方法是將耗時的處理過程轉移到子線程上,這樣可以避免負責界面更新的主線程無法處理界面事件,從而避可以避免負責界面更新的主線程無法處理界面事件,從而避免用戶界面長時間失去響應免用戶界面長時間失去響應多線程概述多線程概述n概述概述 表示一個程序的表示一個程序的多段語句同時執行多段語句同時執行,但并不等于多次啟動一,但并不等于多次啟動一個程序,操作系統也不會把每個線程當作獨立的進程來對待。個程序,操作系統也不會把每個線程當作獨立的進程來對待。n線程和進程區別線程和進程區別兩者的兩者的粒度不同粒度不同,是兩個不

3、同層次上的概念。進程是由,是兩個不同層次上的概念。進程是由操作系統來管理的,而線程則是在一個程序(進程)內。操作系統來管理的,而線程則是在一個程序(進程)內。不同進程的代碼、內部數據和狀態都是完全獨立的,而不同進程的代碼、內部數據和狀態都是完全獨立的,而一個程序內的一個程序內的多線程是共享同一塊內存空間多線程是共享同一塊內存空間和同一組系和同一組系統資源,有可能互相影響。統資源,有可能互相影響。線程本身的數據通常只有線程本身的數據通常只有寄存器數據寄存器數據,以及一個程序執,以及一個程序執行時使用的堆棧,所以線程的切換比進程切換的負擔要行時使用的堆棧,所以線程的切換比進程切換的負擔要小。小。多

4、線程概述多線程概述n線程的狀態和生命周期線程的狀態和生命周期 一個線程從創建、啟動到終止期間的任何時刻,總是處于一個線程從創建、啟動到終止期間的任何時刻,總是處于下面五個狀態中的某個狀態。下面五個狀態中的某個狀態。創建狀態創建狀態 用用new運算符創建一個運算符創建一個Thread類或子類的實例對象,但此類或子類的實例對象,但此時還未對這個線程分配任何資源。時還未對這個線程分配任何資源。 就緒狀態就緒狀態 分配系統資源,由分配系統資源,由start()啟動方法來完成。啟動方法來完成。運行狀態運行狀態當可運行狀態的線程被調度并獲得當可運行狀態的線程被調度并獲得CPU等資源。等資源。多線程概述多線

5、程概述n線程的狀態和生命周期(續)線程的狀態和生命周期(續)阻塞狀態阻塞狀態 由于人為或系統的原因,線程必須停止運行,以后還可以恢由于人為或系統的原因,線程必須停止運行,以后還可以恢復運行的狀態稱為阻塞狀態。復運行的狀態稱為阻塞狀態。 終止狀態終止狀態 run()方法完成后或調用方法完成后或調用stop()或或destroy()方法方法 ,不,不能繼續運行。能繼續運行。多線程概述多線程概述n線程的生命周期及控制線程的生命周期及控制多線程概述多線程概述n線程控制基本方法線程控制基本方法方方 法法功功 能能currentThread() 返回正在運行的Thread對象yield()讓出CPU,當前

6、線程進入就緒隊列等待調度sleep()設置當前線程進入睡眠狀態,時間為指定的毫秒數setName()設置當前線程名稱getName()獲取當前線程名稱isAlive()判斷線程是否還“活”著,即線程是否還未終止getPriority()獲得線程的優先級數值setPriority()設置線程的優先級數值wait()當前線程進入對象的wait poolnotify()notifyAll()喚醒對象的wait pool中的一個/所有等待線程多線程概述多線程概述class SingleThread public void output() Thread t=Thread.currentThread()

7、; t.setName(單線程); t.setPriority(8); System.out.println(The running thread: + t); try for(int i=0; i 3; i+) System.out.println(Sleep time + i); Thread.sleep(500);/ 睡眠500毫秒 catch(InterruptedException e) System.out.println(thread has wrong); public class Test public static void main(String args) Single

8、Thread st=new SingleThread(); st.output(); The running thread: The running thread: ThreadThread單線程單線程,8,main,8,mainSleep time 0Sleep time 0Sleep time 1Sleep time 1Sleep time 2Sleep time 2單線程例單線程例多線程概述多線程概述n創建線程創建線程通過繼承通過繼承Thread類來創建線程類來創建線程class MyThread extends Thread public void run() / 線程需要完成的工作

9、public static void main() / 創建線程 Thread thread1 = new MyThread(); 多線程概述多線程概述n創建線程創建線程通過實現通過實現Runnable接口來創建線程接口來創建線程class MyThread implements Runnable public void run() / 線程需要完成的工作 public static void main() / 創建線程 Thread thread2 = new Thread(new MyThread(); UI線程與非線程與非UI線程線程 nUI線程線程當應用啟動,系統會創建一個主線程(當應

10、用啟動,系統會創建一個主線程(UI線程)線程)處理與處理與UI相關的事件相關的事件 如按鍵事件、用戶接觸屏幕的事件、屏幕繪圖事件等如按鍵事件、用戶接觸屏幕的事件、屏幕繪圖事件等系統不會為每個組件單獨創建線程,在同一個進程里的系統不會為每個組件單獨創建線程,在同一個進程里的UI組件都會在組件都會在UI線程里實例化,系統對每一個組件的線程里實例化,系統對每一個組件的調用都從調用都從UI線程分發出去線程分發出去從從UI線程中操作線程中操作UI組件是安全的組件是安全的非非UI線程中進行線程中進行UI操作不是線程安全的操作不是線程安全的UI線程與非線程與非UI線程線程 n非非UI線程線程非主線程非主線程

11、向向UI線程發出請求消息,由線程發出請求消息,由UI線程處理這些消息,并線程處理這些消息,并進行相關的進行相關的UI操作操作UI線程與非線程與非UI線程線程n非非UI線程線程UI操作錯誤操作錯誤public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); text = (TextView) findViewById(R.id.text); Thread t = new Thread() public void run() /非U

12、I線程 try Thread.sleep(3000); /睡眠3秒 catch (InterruptedException e) e.printStackTrace(); text.setText(UI Thread Test.); ; t.start(); /啟動線程android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. UI線程與非線程與非UI線程線程n非非UI線程線程UI操作錯誤操作錯誤

13、public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView text = (TextView) findViewById(R.id.text); text.setText(Sleep start.); try Thread.sleep(3000); /睡眠3秒 catch (InterruptedException e) e.printStackTrace(); text.setText(Sleep end.

14、);程序運行后,界面上開始是空白的,既沒有之前的“Hello World, HelloDemoActivity!”字樣,也沒有“Sleep start.”字樣,等待3秒鐘后,界面上顯示“Sleep end.” 多線程中的常用類多線程中的常用類nHandler類類 處理較為復雜的線程間通信及消息處理處理較為復雜的線程間通信及消息處理nAsyncTask類類 輕量級基于多線程的進行后臺異步工作處理的類輕量級基于多線程的進行后臺異步工作處理的類nTimer定時器定時器 定時器也是常用的實現多線程程序的方式定時器也是常用的實現多線程程序的方式多線程中的常用類多線程中的常用類nHandler類類非非UI

15、線程向線程向UI線程發出請求消息,由線程發出請求消息,由UI線程處理這些線程處理這些消息,并進行相關的消息,并進行相關的UI操作。這個發送消息和處理消息操作。這個發送消息和處理消息的過程由的過程由Handler類來協助進行處理類來協助進行處理在在UI線程中創建線程中創建Handler類的子類,并通過重寫類的子類,并通過重寫handleMessage(Message msg)方法來實現方法來實現UI操作操作當有其他線程向這個自定義子類的對象發送消息時,當有其他線程向這個自定義子類的對象發送消息時,handleMessage()方法會被調用,通過識別參數方法會被調用,通過識別參數msg的值的值 b

16、oolean sendMessage(Message msg)boolean sendEmptyMessage(int what)多線程中的常用類多線程中的常用類nHandler類類Message類用來封裝所發送消息的值,可以通過類用來封裝所發送消息的值,可以通過Bundle類來封裝這些不同類型的值類來封裝這些不同類型的值 void setData(Bundle data) Bundle getData() 兩個兩個int類型的域變量類型的域變量 一個一個Object類型的域變量作為額外的存儲空間類型的域變量作為額外的存儲空間Bundle類用于提供從字符串到某個具體值的映射,一類用于提供從字符

17、串到某個具體值的映射,一個個Bundle對象可以封裝多個鍵值對對象可以封裝多個鍵值對 void putXXX(String key, XX value) XXX getXXX(String key)多線程中的常用類多線程中的常用類public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView text = (TextView) findViewById(R.id.text); final Handle

18、r handler = new Handler() public void handleMessage(Message msg) /接收消息 super.handleMessage(msg); text.setText(Message Code: + msg.what); ;nHandler類類實現過程實現過程多線程中的常用類多線程中的常用類 Thread t = new Thread() public void run() try Thread.sleep(3000); catch (InterruptedException e) e.printStackTrace(); handler.s

19、endEmptyMessage(1); /發送消息 ; t.start(); /啟動線程多線程中的常用類多線程中的常用類nHandler類類實例:使用多線程模擬秒表應用實例:使用多線程模擬秒表應用 多線程中的常用類多線程中的常用類nAsyncTask類類輕量級的基于多線程的進行后臺異步工作處理的類輕量級的基于多線程的進行后臺異步工作處理的類實現后臺向實現后臺向UI線程傳遞簡單數據線程傳遞簡單數據使用使用AsyncTask類的方法是創建一個子類,重寫其相類的方法是創建一個子類,重寫其相關的方法,然后在關的方法,然后在UI線程中使用線程中使用execute()方法運行方法運行這個自定義類即可這個自

20、定義類即可多線程中的常用類多線程中的常用類nAsyncTask類重寫方法類重寫方法onPreExecute():當后臺任務使用:當后臺任務使用execute()方法運行后,會方法運行后,會立即由立即由UI線程調用,一般用于初始化操作和在界面上顯示后臺任線程調用,一般用于初始化操作和在界面上顯示后臺任務的初始狀態。務的初始狀態。doInBackground(Params.):當:當onPreExecute()方法調方法調用結束后,由后臺線程調用該方法,開始執行后臺任務。在后臺任用結束后,由后臺線程調用該方法,開始執行后臺任務。在后臺任務執行過程中,可以調用務執行過程中,可以調用publishPr

21、ogress(Progress.)方方法向法向UI線程發布當前后臺任務執行的狀態,以便程序界面進行相線程發布當前后臺任務執行的狀態,以便程序界面進行相應的更新。應的更新。onProgressUpdate(Progress.):當后臺線程調用:當后臺線程調用publishProgress(Progress.)方法后,由方法后,由UI線程調用該方線程調用該方法進行法進行UI操作。操作。onPostExecute(Result):當后臺任務全部執行完畢后,由:當后臺任務全部執行完畢后,由UI線程調用該方法,更新界面的顯示,或進行其他的后續操作。線程調用該方法,更新界面的顯示,或進行其他的后續操作。p

22、ublic class HelloDemoActivity extends Activity public void onCreate(Bundle savedInstanceState) . text = (TextView) findViewById(R.id.text); new MyAsyncTask().execute(null); class MyAsyncTask extends AsyncTask public String doInBackground(String. params) try Thread.sleep(3000); publishProgress(50); c

23、atch (InterruptedException e) e.printStackTrace(); return ; public void onProgressUpdate(Integer. values) text.setText(value: + values0); 多線程中的常用類多線程中的常用類nAsyncTask類類實例:使用實例:使用AsyncTask類模擬進度變化類模擬進度變化 多線程中的常用類多線程中的常用類nTimer定時器定時器使用使用Timer類和類和TimerTask類可實現定時器的功能。但是類可實現定時器的功能。但是在定時器中也不能直接進行在定時器中也不能直接進行

24、UI操作,需要使用以下幾種方操作,需要使用以下幾種方式之一來間接地進行式之一來間接地進行UI操作操作通過通過Handler類處理類處理通過通過Activity.runOnUiThread(Runnable)方法方法通過通過View.post(Runnable)方法方法多線程中的常用類多線程中的常用類nActivity.runOnUiThread(Runnable action)該方法被調用后,如果當前線程是該方法被調用后,如果當前線程是UI線程,則立即啟動線程,則立即啟動由參數由參數action所指定的線程所指定的線程如果該方法被調用時的當前線程不是如果該方法被調用時的當前線程不是UI線程,則

25、由參數線程,則由參數action所指定的線程會被放入所指定的線程會被放入UI線程的事件隊列中等線程的事件隊列中等待處理待處理通常程序調用通常程序調用runOnUiThread()方法是在非方法是在非UI線程中線程中進行進行public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); text = (TextView) findViewById(R.id.text); TimerTask task = new TimerTask(

26、) public void run() Thread t = new Thread() public void run() text.setText(runOnUiThread(); ; runOnUiThread(t); /將t線程放入UI線程的事件隊列中等待處理 ; Timer timer = new Timer(); timer.schedule(task, 3000);多線程中的常用類多線程中的常用類多線程中的常用類多線程中的常用類nView.post(Runnable action)action為待啟動線程為待啟動線程nrunOnUiThread()方法會將該線程放入方法會將該線程放

27、入UI線程線程的事件隊列中等待處理的事件隊列中等待處理post()方法是將該線程放入某個方法是將該線程放入某個View對象的消息隊列對象的消息隊列中等待處理。如果能將線程成功放入中等待處理。如果能將線程成功放入View對象的消息對象的消息隊列中,隊列中,post()方法返回方法返回true,否則返回,否則返回false public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); text = (TextView) findVi

28、ewById(R.id.text); TimerTask task = new TimerTask() public void run() Thread t = new Thread() public void run() text.setText(view.post(); ; text.post(t); /將t線程放入當前文本框對象的消息隊列中等待處理 ; Timer timer = new Timer(); timer.schedule(task, 3000);多線程中的常用類多線程中的常用類多線程中的常用類多線程中的常用類nTimer定時器定時器實例:使用實例:使用Timer定時器實現手機內存監視器定時器實現手機內存監視器多線程中的常用類多線程中的常用類nTimer定時器定時器實例:使用實例:使用Timer定時器實現手機內存監視器定時器實現手機內存監視器Android多線程通信機制多線程通信機制nMessageQueue類類消息隊列中可包含多個消息,按照先進先出原則依次處消息隊列中可包含多個消息,按照先進先出原則依次處理。理。MessageQueue不需要由用戶來進行創建和管理,不需要由用戶來進行創建和管理,而是通過而是通過Looper類用來管理

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論