標籤:android style blog color 使用 資料
一、耗時操作
1.什麼是ANR
在應用程式的主線程中執行一段耗時的代碼, 就有可能出現ANR異常.
耗時的代碼未執行結束時, 介面會卡住, 使用者對介面進行了操作, 10秒之後耗時代碼如果還未結束, 就會出現ANR異常
2.怎麼避免ANR
主線程中不要執行耗時的代碼
如果一定要做耗時的事情, 開啟新線程, 在新線程中執行
3.UI Thread
安卓手機中主線程負責重新整理介面, 以及處理使用者的操作
應用程式的介面都是由主線程建立的
介面的修改也只能在主線程中執行
4.Handler
有的時候我們需要執行一些耗時的代碼, 會開啟新線程, 這時又需要更新介面, 必須在主線程中操作, 那麼就需要使用Handler來進行線程之間的通訊
1)sendMessage():
新線程向主線程發送一個包含資料的訊息, 主線程擷取訊息中的資料
在主線程中建立Handler子類對象, 重寫handleMessage()方法
新線程中可以使用Handler的引用調用sendMessage()方法, 發送一個Message對象
只要執行了sendMessage()方法, 那麼主線程會自動執行handleMessage()方法, 收到Message對象
2)post():
新線程向主線程發送一段代碼, 主線程直接執行
在主線程中建立Handler對象
新線程中可以使用Handler調用post()方法發送一個Runnable對象
主線程會自動執行Runable的run()
5.範例程式碼
sendMessage:
package com.gnnuit.anr;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.os.SystemClock;import android.app.Activity;import android.view.Menu;import android.view.View;import android.widget.TextView;public class SendMessageActivity extends Activity { private TextView tv; private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) {// 該方法在sendMessage()方法之後執行, 形參就是發送過來的Message對象 tv.setText(msg.obj + "");// 主線程更新介面 }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.tv); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public void go(View v) { new Thread() { public void run() { for (int i = 1; i < 10; i++) { System.out.println(i + ""); SystemClock.sleep(1000); // Message msg = new Message(); // 建立訊息對象,此種方法效率不高 Message msg = handler.obtainMessage(); // 從訊息池中擷取一個Message msg.obj = i;// 把資料放在訊息對象中 handler.sendMessage(msg);// 在新線程中發送訊息對象, 主線程會自動執行handleMessage()方法 } }; }.start(); }}
post:
package com.gnnuit.anr;import android.os.Bundle;import android.os.Handler;import android.os.SystemClock;import android.app.Activity;import android.view.Menu;import android.view.View;import android.widget.TextView;public class PostActivity extends Activity { private TextView tv; private Handler handler = new Handler(); private int i; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView) findViewById(R.id.tv); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public void go(View v) { System.out.println("go:" + Thread.currentThread().getName() + ""); new Thread() { public void run() { System.out.println("for:" + Thread.currentThread().getName() + ""); for (i = 1;; i++) { System.out.println(i + ""); handler.post(new Runnable() {// 在新線程中使用Handler向主線程發送一段代碼, 主線程自動執行run()方法 @Override public void run() { System.out.println("run:" + Thread.currentThread().getName() + ""); tv.setText(i + ""); } }); SystemClock.sleep(1000); } }; }.start(); }}