android處理耗時任務_ANR
ANR
有些應用在使用中會彈出一個對話方塊,一般這個對話方塊叫做應用程式無響應對話方塊(ANR:Application Not Responding)。雖然這個提示框有等待和關閉應用程式兩種選擇,但是它的彈出就已經影響了使用者使用app過程中的體驗,所以一般來說,Android開發的過程中都會嚴格控制ANR的出現。
ANR表面原因:應用在一定時間內(一般是5秒)沒有響應輸入操作(例如輸入,按鈕,手勢觸摸等)。
ANR根本原因:Android主線程中進行耗時操作,造成主線程阻塞;BroadcastReceiver生命週期結束前沒有完成相應的耗時任務。
Android應用都是運行在主線程中的,包括activity、service的生命週期,ui的重新整理(所以主線程又叫ui線程),輸入響應操作等等。也就是說任何在主線程中啟動並執行函數都不能進行耗時的動作,否則會阻塞主線程,導致輸入無法響應,從而彈出ANR。
BroadcastReceiver的生命週期很短(一般為10秒),如果在它生命週期結束前耗時任務沒有完成,Android認為該程式沒有響應。
這些耗時的操主要包括網路,資料庫,大量的計算操作(如bitmap的處理)等。
簡單的解決方案1、為了防止主線程被阻塞,通常需要啟動子線程來處理耗時任務,子線程的任務完成時通過handler通知主線程,讓主線程重新整理ui等。下面是一個簡單的案例:
import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class MainActivity extends Activity {private TextView text;private Button button;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text = (TextView) findViewById(R.id.text);button = (Button) findViewById(R.id.button);button.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {System.out.println("-->開啟子線程");new TaskThread().start();}});}Handler handler = new Handler() {public void handleMessage(Message msg) {switch (msg.what) {case 0:{System.out.println("-->回到主線程重新整理ui任務");text.setText("任務完成");}break;default:break;}};};class TaskThread extends Thread {public void run() {System.out.println("-->做一些耗時的任務");try {sleep(500);} catch (InterruptedException e) {e.printStackTrace();}handler.sendEmptyMessage(0);};};}運行後列印結果如下:
05-26 05:30:16.490: I/System.out(381): -->開啟子線程
05-26 05:30:16.510: I/System.out(381): -->做一些耗時的任務
05-26 05:30:17.011: I/System.out(381): -->回到主線程重新整理ui任務
2、BroadcastReceiver的函數也是由主線程調用的,但是不應該啟動子線程來處理耗時任務。因為BroadcastReceiver屬於一個空進程,在BroadcastReceiver有限的生命週期結束後他的優先順序就會降低,系統很容易就把它回收了,這樣,子線程的宿主已經被回收了,那麼它的子線程也會被殺死。所以建議在BroadcastReceiver中啟動service,在service中啟動線程處理耗時任務。