Looper如何和一个线程进行绑定,以及Android中的Can't create handler inside thread that has not called Looper.prepare()

Looper如何和一个线程进行绑定,以及Android中的Can't create handler inside thread that has not called Looper.prepare(),第1张

概述Looper如何和一个线程进行绑定,以及Android中的Can't create handler inside thread that has not called Looper.prepare()

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”的文件

[java] view plain copy print ? 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 {            @OverrIDe      protected voID onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentVIEw(R.layout.androID);            button sendbutton = (button) findVIEwByID(R.ID.button);          sendbutton.setonClickListener(new OnClickListener(){              @OverrIDe              public 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();              }          });      }  }  
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(){        @OverrIDe        public 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”的文件
[HTML] view plain copy print ? <relativeLayout xmlns:androID=”http://schemas.android.com/apk/res/android”      xmlns:tools=”http://schemas.android.com/tools”      androID:layout_wIDth=“match_parent”      androID:layout_height=“match_parent”      androID:paddingBottom=“@dimen/activity_vertical_margin”      androID:paddingleft=“@dimen/activity_horizontal_margin”      androID:paddingRight=“@dimen/activity_horizontal_margin”      androID:paddingtop=“@dimen/activity_vertical_margin”      tools:context=“.MainActivity” >       <button         androID:ID=“@+ID/button”         androID:layout_wIDth=“wrap_content”         androID:layout_height=“wrap_content”         androID:layout_centerHorizontal=“true”         androID:layout_centerVertical=“true”         androID:text=“@string/hello” />    </relativeLayout>  
<relativeLayout xmlns:androID=”http://schemas.androID.com/apk/res/androID” 
xmlns:tools=”http://schemas.androID.com/tools”
androID:layout_wIDth=”match_parent”
androID:layout_height=”match_parent”
androID:paddingBottom=”@dimen/activity_vertical_margin”
androID:paddingleft=”@dimen/activity_horizontal_margin”
androID:paddingRight=”@dimen/activity_horizontal_margin”
androID:paddingtop=”@dimen/activity_vertical_margin”
tools:context=”.MainActivity” >

<button
androID:ID=”@+ID/button”
androID:layout_wIDth=”wrap_content”
androID:layout_height=”wrap_content”
androID:layout_centerHorizontal=”true”
androID:layout_centerVertical=”true”
androID:text=”@string/hello” />

</relativeLayout>

        第二种方法:像博客《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线程。






阅读全文


版权声明:本文为博主原创文章,未经博主允许不得转载。 总结

以上是内存溢出为你收集整理的Looper如何和一个线程进行绑定,以及Android中的Can't create handler inside thread that has not called Looper.prepare()全部内容,希望文章能够帮你解决Looper如何和一个线程进行绑定,以及Android中的Can't create handler inside thread that has not called Looper.prepare()所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/1013256.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)