android--多线程,android多线程
線程的基本用法:
android多線程編程其實并不比java多線程特殊,基本都是使用相同的語法,比如說,定義一個線程只需要新建一個類繼承自Thread,然后重寫父類的run()方法,并在里面編寫耗時的邏輯即可,
public classMyThread extends Thread {
@Overridepublic voidrun() {//處理具體的邏輯
super.run();
}
}
如何啟動這個線程,其實也很簡單,只需要new出MyThread的實例,然后調用它的start()方法,這樣run()方法中的代碼就會在子線程當中運行了。
new MyThread().start();
使用繼承的方式耦合性有點高,更多的時候我們都會選擇使用Runnable接口的方式定義一個線程
public classMyThread implements Runnable{
@Overridepublic voidrun() {//處理具體的邏輯
}
}
如果使用了這種寫法,啟動線程的方法也需要進行相應的改變,
MyThread mythread=new MyThread();
new Thread(mythread).start();
當然如果不想專門再定義一個類去實現(xiàn)runnable接口,也可以使用匿名累的方式,如下所示:
Thread thread= new Thread(newRunnable() {
@Overridepublic voidrun() {//具體處理邏輯
}
}).start();
再子線程中更新UI
和許多其他GUI庫一樣,安卓的UI也是線程不安全的,也就是說,如果想要更新應用程序里的UI元素,則必須在主線程中進行,否則就會出現(xiàn)異常。
下面我們來看一個例子:
android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/change_text"android:text="send request"/>
android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/text1"android:text="hello world"android:textSize="20sp"
/>
public classMainActivity extends Activity implements View.OnClickListener {privateTextView textView;privateButton changeText;
@Overrideprotected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.text1);
changeText=(Button)findViewById(R.id.change_text);
changeText.setOnClickListener(this);
}
@Overridepublic voidonClick(View v) {switch(v.getId()){caseR.id.change_text:new Thread(newRunnable() {
@Overridepublic voidrun() {
textView.setText("Nice to neet you");
}
}).start();break;default:break;
}
}
運行的時候會出現(xiàn)如下圖所示的情況:
由此正式了安卓確實是不允許自線程中運行UI操作,但是有時候我們必須在子線程里面去執(zhí)行一些耗時任務,然后根據任務的執(zhí)行結果來更新相應的UI控件,
安卓提供了一套異步消息處理機制完美的解決了在子線程中運行UI操作。
首先我們先來看一下這個解決的代碼
public classMainActivity extends Activity implements View.OnClickListener {privateTextView textView;privateButton changeText;public static final int UPDATE_TEXT=1;private Handler handler=newHandler() {
@Overridepublic voidclose() {
}
@Overridepublic voidflush() {
}
@Overridepublic voidpublish(LogRecord record) {
}public voidhandleMessage(Message msg){switch(msg.what){caseUPDATE_TEXT:
textView.setText("Nice to meet you");break;default:break;
}
}
};
@Overrideprotected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.text1);
changeText=(Button)findViewById(R.id.change_text);
changeText.setOnClickListener(this);
}
@Overridepublic voidonClick(View v) {switch(v.getId()){caseR.id.change_text:new Thread(newRunnable() {
@Overridepublic voidrun() {
Message message=newMessage();
message.what=UPDATE_TEXT;
handler.sendMessage(message);
}
}).start();break;default:break;
}
}
我們來解析異步消息處理機制:
安卓中的異步消息處理主要由四部分組成,Message,Handler,MessageQueue和Looper。
1 Message
Message是在線程之間傳遞的消息,它可以在內部攜帶少量的信息,用于在不同線程之間交換數(shù)據。
2 Handler
Handler故名思義也就是處理者的意思,它主要是用于發(fā)送和處理消息的,發(fā)送消息一般是使用Handler的sendmessage()方法,而發(fā)出的消息經過一系列地輾轉處理后,最終會傳遞到Handler地handleMessage()方法中,
3MessageQueue
MessageQueue 是消息隊列的意思,它主要用于存放所有通過Handler發(fā)送的消息,這部分消息會一直存在于消息隊列中,等待被處理,每個線程中只會有一個MessageQueue對象。
4 Looper
Looper是每個線程中的MessageQueue的管家,調用Looper的loop()方法后,就會進入到一個無限循環(huán)當中,然后每當發(fā)現(xiàn)MessageQueue中存在一條消息,就會將它取出,并傳遞到Handler的handleMessage()方法中,每個線程中也只會只有一個Looper對象。
首先需要在主線成中創(chuàng)建一個Handler對象,并重寫handleMessage()方法,然后子線程中需要進行UI操作時,就創(chuàng)建一個Message對象,并通過Handler將這條消息發(fā)送出去,之后這條消息會被添加到MessageQueue的隊列中等待被處理,而Looper則會一直嘗試從MessageQueue中取出待處理消息,最后奮發(fā)回Handler的handleMessage()方法中,由于Handle是在主線程中創(chuàng)建的,所以此時handleMessage()方法中的代碼也會在主線成中運行,于是我們在這里就可以安心的運行UI操作,整個異步消息處理的核心思想就是這樣。
為了更加方便我們在自線程中對UI進行操作,android還提供了另外的一些好用的工具,AsyncTask就是其中之一,借助AsyncTask,即使你對異步消息處理機制完全不了解,也可以十分簡單的從子線程切換的主線程,AsyncTask背后的實現(xiàn)原理也是基于異步消息處理機制的。
由于AsyncTask是一個抽象類,所以如果我們想要使用它,就必須創(chuàng)建一個子類去繼承它,在繼承AsyncTask類指定三個范性參數(shù),這三個參數(shù)的用途如下:
1 params
在執(zhí)行AsyncTask時需要傳入參數(shù),用于在后臺任務中使用。
2progress
后臺任務執(zhí)行時,如果需要在界面上顯示當前的進度,則使用這里指定的范性作為進度單位。
3 result
當任務執(zhí)行完畢后,如果需要對結果進行返回,則使用這里指定的泛型作為返回類型。
我們還需要自定義一些方法才能完成對任務的定制。
1 onPreExecute()
這個方法會在后臺任務開始執(zhí)行之前調用,用于進行一些界面上的初始化操作,比如顯示一個進度條對話框
2 doInBackground(Params...)
這個方法中所有代碼都會在自線程中運行,我們應該在這里去處理所有的耗時任務,任務一旦完成就可以通過return語句來將任務的執(zhí)行結果返回,如果AsyncTask的讀三個泛型參數(shù)指定的是void,就可以不返回任務執(zhí)行結果,注意,在這個方法中是不可以進行ui操作的,如果要更新UI元素,比如說反饋當前任務的執(zhí)行進度,可以調用publishProgress(Progress...)方法來完成。
3 onProgressUpdate(Progress...)
當在后臺任務中調用了publishprogress(progress...)方法后,這個方法就會很快被調用,方法中攜帶的參數(shù)就是在后臺任務傳遞過來的,在這個方法中可以對UI進行操作。利用參數(shù)中的數(shù)值就可以對界面元素進行相應的更新。
4 onPostExecute(Result)
當后臺任務執(zhí)行完畢并通過return語句進行返回時,這個方法就很快會被調用,返回的數(shù)據會作為位參數(shù)傳遞到此方法中,可以利用返回的數(shù)據來進行一些UI操作,比如說提醒任務執(zhí)行的結果以及關閉掉進度條對話框。
如果要啟動的話只需要調用其execute()方法。
總結
以上是生活随笔為你收集整理的android--多线程,android多线程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HBase Java API 代码开发
- 下一篇: 自动化交易综述——互联网金融