產生進度對話窗很容易,要關掉比較複雜一點。
一般會需要進度對話窗就是有較費時的工作要處理,但是因為 Android 有五秒鐘的回應限制,所以不能在 main thread 裡直接進行費時的運算,要用 worker thread,也就是另外起一個 thread 來負責費時的運算,但因為是另一個 thread,所以不能像 main thread 一樣可以控制 UI,也就是說,當 worker thread 執行完成時,得透過 Handler 來告訴 main thread,並且視需要傳遞運算結果給 main thread。
所以整個流程如下:
- main thread 產生進度對話窗
- main thread 建立 handler
- main thread 建立 worker thread 進行費時的運算,並將 handler 傳給 worker thread
- worker thread 完成運算後,透過 handler 讓 main thread 知道
- main thread 呼叫 handler 的 callback method 來關閉進度對話窗
ProgressActivity
public class ProgressActivity extends Activity { private static final String TAG = "ProgressActivity"; private ProgressDialog progressDialog; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Utils.logThread(); // 建立並顯示進度對話窗 this.progressDialog = new ProgressDialog(this); this.progressDialog.setTitle("執行中"); this.progressDialog.setMessage("請稍後..."); this.progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); this.progressDialog.show(); // 建立 worker thread,並交付由 main thread 建立的 handler // 供 worker thread 稍後與 main thread 溝通 new Thread(new DoSomethingThread(this.handler)).start(); } private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { Utils.logThread();
// main thread 從 main queue 取得 handler 丟進來的 message // 再從該 message 取得 handler 物件 // 最後呼叫 handler 的 callback method - handleMessage 來關閉進度對話窗 progressDialog.dismiss(); } }; }DoSomethingThread
public class DoSomethingThread implements Runnable { private Handler handler; public DoSomethingThread(Handler handler) { super(); this.handler = handler; } @Override public void run() { Utils.logThread();
// 停頓五秒鐘後,通知 main thread 關閉進度對話窗 try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }
// 丟一個 message 到 main queue 裡,由 main thread 接手處理 this.handler.sendEmptyMessage(0); } }Utils
public class Utils { private static final String TAG = "Utils"; public static final void logThread() { Thread t = Thread.currentThread(); Log.d(TAG, "<" + t.getName() + ">id: " + t.getId() + ", Priority: " + t.getPriority() + ", Group: " + t.getThreadGroup().getName()); } }thread 的執行過程可以從 log 看出來:
10-27 12:29:52.747: DEBUG/Utils(643): <main>id: 1, Priority: 5, Group: main 10-27 12:29:52.917: DEBUG/Utils(643): <Thread-10>id: 10, Priority: 5, Group: main 10-27 12:29:57.919: DEBUG/Utils(643): <main>id: 1, Priority: 5, Group: main
再看看 使用 Android 百分比進度對話窗 ProgressDialog。
沒有留言:
張貼留言