多線程編程
執行一條耗時操作,需放在子線程裏運行
1、線程的基本用法
新建類繼承 或實現接口 ,重寫方法--(可直接內部類)
● class MyThread extends Thread { ~run () { //處理具體的邏輯 } }
new MyThread( ).start ( ) ; // 使用則 new一個實例即可
● class MyThread implements Runnable { ..}
MyThread runnable= new Runnable ( ); //生成一個Runnable對象
new Thread( runnable) .start( ); //Thread 構造函數接收Runnable 對象
● new Thread( new Runnable ( ){....} ).start( ) ;
2、在子線程中更新UI
不能直接在線程彙總更新UI (不安全) 使用異步消息處理機制 ,在子線程對 UI操作(傳遞消息)
..... public static final int UPDATE_TEXT=1 ;
private Handler handler= new Handler ( ) {
~handleMessage( Message msg ) {
swith( msg.what) {
case UPDATE_TEXT:
text_textView.setText( " .....設置修改文本內容 " ); //在這裏進行UI操作
......
.....onClick( ){ //點擊事件 爲要對UI操作的對象 ,用消息發出去
swith( ....) {
case .... :
new Thread( new Runnable ( ) { ...run ( ) {
Message message=new Message( ) ;
message.what=UPDATE_TEXT;
handler.sendMessage( message ); //將Message發出去
...).start( ) ;
異步消息處理機制
由4部分組成:Message 、Handler 、MessageQueue 、Looper
1、Message :消息
在線程之間傳遞的消息,可以在內部攜帶少量的信息,用於在不用的線程之間交換數據。
2、Handler :處理者
發送和處理消息 。發送sendMessage()傳送到handleMessage()
3、MessageQueue :消息隊列
存放所有通過Handler發送的消息 ,每個線程只有一個
4、Looper------MQ(消息隊列)的管家
調用Looper的loop(),進入無線循環,每當發現MQ中存在一條 消息就會將它取出,傳遞到Handler的handleMessage()中,每一 個線程只有一個Looper對象
在主線程創建Handler對象——>重寫handleMessage()——>子線程中傳遞消息
1、使用AsyncTask
抽象類,繼承時可指定三個泛型參數:
⑴ Params---執行AsyncTask 時需輸入,可用於在後臺任務中使用
⑵ Progress---後臺任務執行時,若需要在前端顯示進度,可作爲進度單位
⑶ Result---任務執行完閉,若需返回結果,可作爲返回類型
eg: class DownloadTask extends AsyncTask< Void ,Integer ,Boolean > { .... } //重寫 方法,完成對任務的定製
可實現的方法:
⑴ onPreExecute( )---在後臺任務開始執行前調用,用於進行一些界面上的初始化操作,如進度條對話框顯示
⑵ doInBackground( Params ....)---所有代碼都在子線程中運行,在這裏去處理所有耗時任務。任務完成通過return 將結果返回。不可盡心UI操作
⑶ onProgressUpdate( ... )----當在後臺任務中調用了 publishProgress ()後,此方法會很快被調用 ,方法攜帶的參數就是在後臺任務中傳遞過來。可對UI進行操作,利用參數中的數值可對界面中元素更新
⑷ onPostExecute( Result )--- doInBackground( Params ....)方法後,次方法很快被調用,返回的數據會作爲參數傳遞到此方法中,可利用
onProgressUpdate( ... )方法進行一些UI操作
●在 doInBackground( Params ....) 中進行具體的耗時任務
●在 onProgressUpdate( ...
) 進行UI操作
●在 onPostExecute( Result ) 執行一些任務的收尾工作
啓動任務: new DownloadTask( ).execute( ) ;