耗時操作ANR和handler
阿新 • • 發佈:2019-01-21
耗時操作
1.什麼是ANR
在應用程式的主執行緒中執行一段耗時的程式碼, 就有可能出現ANR異常.
耗時的程式碼未執行結束時, 介面會卡住, 使用者對介面進行了操作, 10秒之後耗時程式碼如果還未結束, 就會出現ANR異常
* 2.怎麼避免ANR
主執行緒中不要執行耗時的程式碼
如果一定要做耗時的事情, 開啟新執行緒, 在新執行緒中執行
3.UI Thread
安卓手機中主執行緒負責重新整理介面, 以及處理使用者的操作
應用程式的介面都是由主執行緒建立的
介面的修改也只能在主執行緒中執行
** 4.Handler
有的時候我們需要執行一些耗時的程式碼, 會開啟新執行緒, 這時又需要更新介面, 必須在主執行緒中操作, 那麼就需要使用Handler來進行執行緒之間的通訊
a.sendMessage():
新執行緒向主執行緒傳送一個包含資料的訊息, 主執行緒獲取訊息中的資料
在主執行緒中建立Handler子類物件, 重寫handleMessage()方法
新執行緒中可以使用Handler的引用呼叫sendMessage()方法, 傳送一個Message物件
只要執行了sendMessage()方法, 那麼主執行緒會自動執行handleMessage()方法, 收到Message物件
b.post():
新執行緒向主執行緒傳送一段程式碼, 主執行緒直接執行
在主執行緒中建立Handler物件
新執行緒中可以使用Handler呼叫post()方法傳送一個Runnable物件
1.什麼是ANR
在應用程式的主執行緒中執行一段耗時的程式碼, 就有可能出現ANR異常.
耗時的程式碼未執行結束時, 介面會卡住, 使用者對介面進行了操作, 10秒之後耗時程式碼如果還未結束, 就會出現ANR異常
* 2.怎麼避免ANR
主執行緒中不要執行耗時的程式碼
如果一定要做耗時的事情, 開啟新執行緒, 在新執行緒中執行
3.UI Thread
安卓手機中主執行緒負責重新整理介面, 以及處理使用者的操作
應用程式的介面都是由主執行緒建立的
介面的修改也只能在主執行緒中執行
** 4.Handler
有的時候我們需要執行一些耗時的程式碼, 會開啟新執行緒, 這時又需要更新介面, 必須在主執行緒中操作, 那麼就需要使用Handler來進行執行緒之間的通訊
a.sendMessage():
新執行緒向主執行緒傳送一個包含資料的訊息, 主執行緒獲取訊息中的資料
在主執行緒中建立Handler子類物件, 重寫handleMessage()方法
新執行緒中可以使用Handler的引用呼叫sendMessage()方法, 傳送一個Message物件
只要執行了sendMessage()方法, 那麼主執行緒會自動執行handleMessage()方法, 收到Message物件
b.post():
新執行緒向主執行緒傳送一段程式碼, 主執行緒直接執行
在主執行緒中建立Handler物件
新執行緒中可以使用Handler呼叫post()方法傳送一個Runnable物件
主執行緒會自動執行Runable的run()
執行結果圖:
示例程式碼:
package com.oterman.myhandler; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.view.View; import android.widget.TextView; public class MainActivity extends Activity { TextView tv1=null; TextView tv2=null; int j; //sendmessage方式; Handler msgHandler=new Handler(){ public void handleMessage(Message msg) { tv1.setText(msg.obj.toString()); } }; Handler postHandler=new Handler();//post方式 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv1=(TextView) findViewById(R.id.tv1); tv2=(TextView) findViewById(R.id.tv2); } //按鈕一點選相應函式 public void go1(View v){ tv1.setText("軍哥好"); new Thread(new Runnable() { public void run() { for(int i=0;;i++){ //採取傳送訊息的方式,將主執行緒要執行的程式碼封裝成訊息物件,然後send出去; Message msg=new Message(); msg.obj=i; msgHandler.sendMessage(msg); SystemClock.sleep(1000); } } }){}.start(); } //按鈕2的點選響應函式,採用post方式提交要處理的訊息給主執行緒; public void go2(View v){ tv2.setText("俊哥棒"); System.out.println("go:"+Thread.currentThread().getName()); new Thread(new Runnable() { public void run() { for(j=0;;j+=2){ System.out.println("for:"+Thread.currentThread().getName()); postHandler.post(new Runnable() { public void run() {//主執行緒要執行的程式碼; System.out.println("post_run:"+Thread.currentThread().getName()); tv2.setText(j+""); } }); SystemClock.sleep(1000); } } }){}.start(); } }