在 Android 的開發規則裡有一個規定
就是所有與網路連線的功能都必須在另一個執行緒內執行
而另一個相關的重要規定是
所有與 UI 相關的功能只能在 UI Thread 內執行(也就是主執行緒)
這項規定是由於程式執行流暢度的考量而產生的
但這麼一來
若在其他執行緒的做完某件事情時 該如何使用 UI 告知使用者呢?
這時就需要用到 Thread 搭配 Handler 的 Design Pattern 了
當然還有其他的選項 例如 AsyncTask
但為了最大的開發自由度
我建議還是使用 Thread 搭配 Handler 會較一勞永逸
當然還是要看情況而定
廢話不多說 我們來看看該如何使用這項功能
這裡同時會用到 WeakReference 的 Design Pattern
會在另一個教學文章 WeakReference 與多執行緒的 Handler 提到
- // Handler in main activity
- private SSHThreadHandler sshHandler = new SSHThreadHandler(this);
- private static class SSHThreadHandler extends Handler{
- private WeakReference<MainActivity> refActivity;
- public SSHThreadHandler(MainActivity activity) {
- refActivity = new WeakReference<>(activity);
- }
- @Override
- public void handleMessage(Message message){
- MainActivity activity = refActivity.get();
- SSHConnection sshConnection = activity.getSshConnection();
- TextView redirectPageStatus = activity.getRedirectPageStatus();
- switch(message.what){
- case SSHConnection.waitingUsername:
- sshConnection.inputUsername();
- redirectPageStatus.setText( "連線中... 快好囉~" );
- break;
- case SSHConnection.waitingPassword:
- sshConnection.inputPassword();
- break;
- case ISSHConnection.waitingDuplicateConfirm:
- activity.showDuplicateLoginAlert();
- break;
- case SSHConnection.waitingContinueConfirm:
- sshConnection.doContinue();
- redirectPageStatus.setText( "歡迎回來 " + sshConnection.getUsername() );
- break;
- case SSHConnection.menuPage:
- activity.hideLoginPageFrame();
- activity.hideLoadingFrame();
- activity.showMenuPageHolder();
- break;
- }
- }
- }
- // 其他執行緒與 Handler 互動的方式
- public static final int connected = 0;
- public static final int waitingUsername = 1;
- public static final int waitingPassword = 2;
- public static final int waitingDuplicateConfirm = 3;
- public static final int waitingContinueConfirm = 4;
- public static final int menuPage = 5;
- @Override
- public void connect(String username, String password, Handler handler) throws IOException {
- if( somthingHappened ){
- sendMessage( doSomething );
- }
- else{
- sendMessage( doAnother );
- }
- }
- /**
- * Send message to the UI thread.
- */
- private void sendMessage(int msg){
- Message message = new Message();
- message.what = msg;
- handler.sendMessage(message);
- }