谷歌在4.0系統以後就禁止在主線程中進行網絡訪問瞭,原因是:
主線程是負責UI的響應,如果在主線程進行網絡訪問,超過5秒的話就會引發強制關閉,所以這種耗時的操作不能放在主線程裡。放在子線程裡,而子線程裡是不能對主線程的UI進行改變的,因此就引出瞭Handler,主線程裡定義Handler,子線程裡使用。
主線程的Handler定義:
Handler loginHandler = new Handler() { public void handleMessage(Message msg) { isNetError = msg.getData().getBoolean("isNetError"); System.out.println(isNetError); if (proDialog != null) { proDialog.dismiss(); } if (isNetError) { Toast.makeText(LoginActivity.this, "登陸失敗:\n1.請檢查您網絡連接.\n2.請聯系我們!", Toast.LENGTH_LONG).show(); } // 用戶名和密碼錯誤 else { Toast.makeText(LoginActivity.this, noticeMsg, Toast.LENGTH_LONG).show(); // 清除以前的SharePreferences密碼 clearSharePassword(); } } };
主線程裡進行登錄時候的子線程:
// 開一個線程進行登錄驗證,主要是用於失敗,成功直接通過startAcitivity(Intent)轉向 Thread loginThread = new Thread(new LoginFailureHandler()); loginThread.start();
子線程的對Handler的使用:
/** * 登錄處理函數 * @author wangfeng * @date 2013-12-19 09:25:42 * */ class LoginFailureHandler implements Runnable { @Override public void run() { /*userName = userNameEdit.getText().toString(); password = loginPasswordEdit.getText().toString();*/ //驗證地址 String validateURL=url+"/login"; boolean loginState = validateLocalLogin(userNameEdit.getText().toString(), loginPasswordEdit.getText().toString(), validateURL); Log.d(this.toString(), "validateLogin"); // 登陸成功 //測試---開始 loginState = true; //---測試結束 if (loginState) { // 需要傳輸數據到登陸後的界面, Intent intent = new Intent(); intent.setClass(LoginActivity.this, ListViewActivity.class); Bundle bundle = new Bundle(); /*bundle.putString("MAP_USERNAME", userNameEdit.getText().toString()); intent.putExtras(bundle);*/ // 轉向登陸後的頁面 proDialog.dismiss(); startActivity(intent); } else { // 通過調用handler來通知UI主線程更新UI, Message message = new Message(); Bundle bundle = new Bundle(); bundle.putBoolean("isNetError", isNetError); message.setData(bundle); loginHandler.sendMessage(message); } } }
通過messgae.setData方法吧Budle帶進去,然後通過Handler.sendMessage把message放進去.在Handler的handlerMessage中處理。