1. 程式人生 > >耗時操作ANR和handler

耗時操作ANR和handler

耗時操作
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();
    }


}