#眉標=Mobile、Android、ANR #副標=剖析Android平台手機程式開發 #大標=解決Android手機發生ANR問題的技巧 #作者=文/圖 花繼利 ====================== 程式1 package example.demo; import example.demo.tools.Utilities; import example.demo.perfectprogress.CallbackHandler; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import demo.ui.UserLogin; public class ProgressDemo extends Activity { private String realm = null; private String altMsg = null; private Handler handler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.main);  // 顯示來自layout資源設定的UI內容 this.initNetworkResource(); // 呼叫initNetworkResource() 初始化網路資源 } private void initNetworkResource() { // 呼叫startCallbackHandler() 顯示進度對話視窗(計時30秒,計時截止警告訊息) Utilities.startCallbackHandler(this, 30000, CallbackHandler. WARNING_MSG); new Thread() { public void run() { // 呼叫isNetworkStarted() 在執行緒中檢驗網路資源是否正常 if (ProgressDemo.this.isNetworkStarted()) {  ProgressDemo.this.getRealm(); if (ProgressDemo.this.realm == null) // 警告未取得伺服器回應 ProgressDemo.this.alertWarning("伺服器沒有回應!"); else { // 退出進度對話視窗 Utilities.stopCallbackHandler();  // 開啟HelloWorld sub-Activity ProgressDemo.this.startActivity(new    Intent(ProgressDemo.this, HelloWorld.class)); } } // 警告無網路設備 else ProgressDemo.this.alertWarning("請設定網路設備!"); Utilities.stopCallbackHandler(); // 退出進度對話視窗 } }.start(); } public void alertWarning(String altMsg) { this.altMsg = altMsg; this.handler.post(new Runnable() // 在執行緒中透過Handler來顯示使用者介面 { @Override public void run() {// 顯示警告對話視窗 Utilities.alertDialog(ProgressDemo.this, ProgressDemo.this.altMsg, true); } }); } private String getRealm() { //模擬向網路伺服器取得網域值 return this.realm; } private boolean isNetworkStarted() { //模擬網路設備連線檢查 return true; } } ====================================== ====================== 程式2 package example.demo.tools; import example.demo.perfectprogress.CallbackHandler; import android.content.DialogInterface.OnClickListener; import android.content.*; import android.app.AlertDialog; public class Utilities { private static CallbackHandler callbackHandler = null; public static CallbackHandler startCallbackHandler(Context context, long time, int finishHandleMsg) { callbackHandler = new CallbackHandler(context, "正在進行運算中。。。", finishHandleMsg); //初始化設定進度對話視窗處理器 callbackHandler.setupCallBackTimer(time); //初始化設定計時器 callbackHandler.sendMessage(callbackHandler.obtainMessage(CallbackHandler. START_PROGRESS_BAR)); return callbackHandler; } public static void stopCallbackHandler() { if (callbackHandler != null)  callbackHandler.sendMessage(callbackHandler.obtainMessage(CallbackHandler.   STOP_PROGRESS_BAR)); callbackHandler = null; } public static AlertDialog alertDialog(Context context, String msg, Boolean enableDismissButton) //建構警告對話視窗 { AlertDialog alertDlg = new AlertDialog.Builder(context).create(); alertDlg.setMessage(msg);  //設定警告對話視窗主體內容 alertDlg.setTitle(“警告”);  //設定警告對話視窗標題 alertDlg.setIcon(android.R.drawable.ic_dialog_alert); // 設定警告對話視窗圖示 alertDlg.setCancelable(false);  //不允許強制退出警告對話視窗 if (enableDismissButton)  //顯示退出警告對話視窗的按鈕 alertDlg.setButton(“確定”, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss();//退出警告對話視窗 } }); alertDlg.show(); //開始顯示警告對話視窗 return alertDlg; } } ====================================== ====================== 程式3 package example.demo.perfectprogress; import example.demo.ProgressDemo; import android.app.ProgressDialog; import android.content.Context; import android.os.*; import android.util.Log; public class CallbackHandler extends Handler { private final String TAG = this.getClass().getSimpleName(); public static final int EMPTY_MSG = -1; public static final int WARNING_MSG = 0; public static final int START_PROGRESS_BAR = 98; public static final int STOP_PROGRESS_BAR = 99; private static final long TICKER = 1000; private int finishHandleMsg = EMPTY_MSG; private Context context = null; private String progressLabel = null; private ProgressDialog progDlg = null; private CountDownTimer callbackTimer = null; public CallbackHandler(Context context, String label, int finishHandleMsg) { this.context = context; this.progressLabel = label; // 設定進度指示對話視窗主體內容 this.finishHandleMsg = finishHandleMsg; // 超過期限時送給Handler處理的訊息 this.progDlg = new ProgressDialog(context); // 建立進度指示對話視窗 } @Override public void handleMessage(Message msg) // 依據所接收到的handler訊息進行處理 { switch (msg.what) { case START_PROGRESS_BAR: Log.i(TAG, "CallbackHandler process : msg.what = START_PROGRESS_BAR !!!"); this.progDlg.setTitle("請稍候片刻"); //設定進度指示對話視窗標題 this.progDlg.setIndeterminate(true); this.progDlg.setCancelable(false); //不允許強制退出進度指示對話視窗 this.progDlg.show();//開始顯示進度指示對話視窗 if (this.callbackTimer != null)this.callbackTimer.start();//開始計時 break; case STOP_PROGRESS_BAR: Log.i(TAG, "CallbackHandler process : msg.what = STOP_PROGRESS_BAR !!!"); if (this.callbackTimer != null) this.callbackTimer.cancel();//取消計時 this.progDlg.dismiss();//退出進度指示對話視窗的顯示 break; case WARNING_MSG: //送出警告對話視窗 ((ProgressDemo) this.context).alertWarning(“請設定網路設備!”); break; default: //送給Handler請求退出進度指示對話視窗顯示處理的訊息 this.sendMessage(CallbackHandler.this.obtainMessage( STOP_PROGRESS_BAR)); } super.handleMessage(msg); } public void setupCallBackTimer(long time) { Log.d(TAG, "Setup CallbackHandler.class Timer ..."); this.callbackTimer = new CountDownTimer(time, CallbackHandler.TICKER) {//初始化設定計時器 public void onTick(long millisUntilFinished) {//每隔millisUntilFinished毫秒,更新進度指示對話視窗主體內容顯示 CallbackHandler.this.progDlg.setMessage(CallbackHandler.this. progressLabel + " ( " + millisUntilFinished / 1000 + " )"); } public void onFinish() {// 計時截止時,退出進度指示對話視窗顯示 CallbackHandler.this.sendMessage(CallbackHandler.this. obtainMessage(STOP_PROGRESS_BAR)); if (CallbackHandler.this.finishHandleMsg != CallbackHandler.EMPTY_MSG) {//送給Handler請求處理的訊息 CallbackHandler.this.sendMessage(CallbackHandler.this. obtainMessage(CallbackHandler.this.finishHandleMsg)); } } }; } } ====================================== ====================== 參考文獻 ●《Android應用框架原理與程式設計36技》,第一章認識應用框架。 ●《Unlocking Android,A Developer’s Guide》,Chapter 1:Targeting Android。 ●《Professional Android Application Development》,Chapter 1:Hello, Android。 ●《Good Android SDK開發範例大全》,第三章使用者人機介面。 ======================================