博客《Android客户端和服务器端数据交互的第三种方法》中Android手机客户端代码1曾经提到“第41行和第61行不可缺少,否则会出现java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()异常”,呵呵呵,难道将"第41行和第61行"代码注销掉以后真的会出现这个异常?嗯嗯嗯,这是一个事实,可是如果把"第41行和第61行"代码注销掉并且把“第50行”代码改为“System.out.println(EntityUtils.toString(httpResponse.getEntity()));”,这时再次运行Android客户端就会发现程序没有任何问题,为什么会这样?很简单,一句话Android中不能在子线程中刷新UI线程。那么问题来了,如果需要在子线程中刷新UI线程怎么办?有如下两种方法:

        第一种方法:像博客《Android客户端和服务器端数据交互的第三种方法》中说的那样添加"第41行和第61行"代码;

        第二种方法提到了Looper类,那么怎么理解这个类呢?

        Looper类用来为一个子线程开启一个消息循环。默认情况下Android中新诞生的非主线程没有开启消息循环(主线程诞生时系统会自动为其创建开启消息循环的Looper对象),所以在非主线程中直接new Handler()会报“java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()”异常,需要先调用Looper.prepare()启用Looper,然后通过调用Looper.loop()让Looper开始工作,如下代码:

        代码1:名为“AndroidActivity.java”的文件

package com.example.androidclient;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;public class AndroidActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.android);Button sendButton = (Button) findViewById(R.id.button);sendButton.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {new Thread(new Runnable(){    @Override    public void run() {    Looper.prepare();    Message message = new Message();                          Bundle bundle = new Bundle();    Handler handler = new Handler(){              @Override              public void handleMessage(Message message) {                  super.handleMessage(message);                  Bundle bundle = message.getData();                  String msg = bundle.getString("msg");                  Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();              }          };                bundle.putString("msg", "你好!!!");                message.setData(bundle);                          handler.sendMessage(message);    Looper.loop();    }}).start();}});}}
        代码2:名为“android.xml”的文件
   

        第二种方法:像博客《Android客户端和服务器端数据交互的第二种方法》中做的那样在子线程中添加Handler来发送消息更新UI线程。

        第二种方法提到了HandlerHandler,可是怎样理解它呢?

        Handler主要用于接收子线程发送的数据并用此数据配合主线程更新UI线程. 
        解释: 当Android应用程序启动时,它首先会开启一个主线程 (也就是UI线程), 主线程为管理界面中的UI控件,进行事件分发, 比如说, 点击一个Button, Android会将事件分发到该Button上来响应操作。如果点击按钮后需要一个耗时的操作(比如联网读取数据或者读取本地较大的一个文件),你不能把这些操作放在主线程中,放在主线程界面会出现假死现象, 如果5秒钟还没有完成,则会收到Android系统的一个错误提示"强制关闭",这个时候我们需要把这些耗时的操作放在一个子线程中,又因为子线程涉及到UI更新,而Android主线程不安全的,所以只能在主线程中更新UI线程,子线程中操作是危险的。这种情况下,Handler的出现解决这个复杂的问题,由于Handler运行在主线程中(UI线程中),它与子线程可以通过Message对象来传递数据,这个时候,Handler就承担着接收子线程传过来的(子线程用sedMessage()方法传弟)Message对象(该对象携带者子线程传入的数据)并把这些数据放入主线程队列中以配合主线程更新UI线程。

更多相关文章

  1. mybatisplus的坑 insert标签insert into select无参数问题的解决
  2. python起点网月票榜字体反爬案例
  3. 《Android开发从零开始》——25.数据存储(4)
  4. Android系统配置数据库注释(settings.db)
  5. Android中不同应用间实现SharedPreferences数据共享
  6. 浅析Android中的消息机制-解决:Only the original thread that cr
  7. Android异步消息机制之Handler
  8. Android的Handler机制详解3_Looper.looper()不会卡死主线程
  9. android图表ichartjs

随机推荐

  1. ANDROID ANT打包
  2. Android开发框架xUtils3.x新手教学(二)HT
  3. Android(安卓)Studio 升级和新版本下载
  4. NDK 环境配置 (Ubuntu)
  5. webview 播放H5视频问题 黑屏 只有声音没
  6. android IO操作
  7. 安卓seekBar的使用(初学者)
  8. NestedScrollView、ScrollView 加载完自
  9. React Native项目组织结构介绍
  10. android 播放网络或本地gif格式的动态图