谷歌在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中处理。