Android App在线程中创建handler的方法讲解_Android

相关概念
1.Handler:可以看做是一个工具类,用来向消息队列中插入消息的;
2.Thread:所有与Handler相关的功能都是与Thread密不可分的,Handler会与创建时所在的线程绑定;
3.Message:消息;
4.MessageQueue:消息队列,对消息进行管理,实现了一个Message链表;
5.Looper:消息循环,从MessageQueue中取出Message进行处理;
6.HandlerThread:继承Thread,实例化时自动创建Looper对象,实现一个消息循环线程.

在Android开发中经常会使用到线程,一想到线程,一般都会想到:

new Thread(){...}.start();

这样的方式。这样如果在一个Activity中多次调用上面的代码,那么将创建多个匿名线程,如果这些线程的没有被销毁,那肯定会影响性能呢。这个时候我么就想到了android提供的一个异步处理线程的类HandlerThread。

一般Handler的用法

Handler handler = new Handler(){...};

这样创建的handler是在主线程即UI线程下的Handler,即这个Handler是与UI线程下的默认Looper绑定的(当然也只有主线程才能这么干,子线程是干不了的,除非自己创建个looper)。因此,有些时候会占用ui主线程,引起一些问题,所以我们就想到了重新创建个子线程,来处理handler。。。。
使用HandlerThread解决问题

HandlerThread实际上继承于Thread,只不过它比普通的Thread多了一个Looper。我们可以使用下面的例子创建Handler

HandlerThread thread = new HandlerThread("MyHandlerThread");
thread.start();

创建HandlerThread时要把它启动了,即调用start()方法。

接着就是handler的使用,如下:

mHandler = new Handler(thread.getLooper());
//TODO:you can post or send something....

创建Handler时将HandlerThread中的looper对象传入。那么这个mHandler对象就是与HandlerThread这个线程绑定了(这时就不再是与UI线程绑定了,这样它处理耗时操作将不会阻塞UI)。

线程中消息处理的流程图

消息插入队列的位置由参数uptimeMillis来确定。

Handler与线程的关系

1.HandlerThread就是一个封装了Looper的Thread.
2.Handler会与实例化时所在的线程绑定.

UI线程与子线程通信相关

1.需要更新UI,则需要使用与主线程绑定的Handler发送消息,若使用在子线程中创建的Handler则会抛出异常;
2.子线程中实例化Handler对象首先需要调用Looper.prepare(),否则会抛出异常;
3.调用Looper.loop()方法消息循环才会启动;
使用Handler时一些需要注意的地方
Looper.prepare(),主线程使用handler,系统默认prepare了,子线程中创建handler必须在前面Looper.prepare(),后面加上Looper.loop();

源码中:
主线程:
在程序启动的时候,系统已经帮我们自动调用了Looper.prepare()方法。查看ActivityThread中的main()

public static void main(String[] args) {
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
  sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
  Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}

请注意Looper.prepareMainLooper():

public static final void prepareMainLooper() {
prepare();
setMainLooper(myLooper());
if (Process.supportsProcesses()) {
  myLooper().mQueue.mQuitAllowed = false;
}
}

子线程:

new Thread(new Runnable() {
    @Override
    public void run() {
      Looper.prepare()
      handler2 = new Handler();
      Looper.loop()
    }
  }).start();

如果没有Looper.prepare().会报错:

Can't create handler inside thread that has not called Looper.prepare()
因为没looper对象创建

looper.prepare()源码:

public static final void prepare() {
if (sThreadLocal.get() != null) {
  throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
} 

    
   

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索android
, 线程
handler
子线程创建handler、子线程中创建handler、线程中创建handler、android子线程handler、android handler 线程,以便于您获取更多的相关知识。

时间: 2024-11-02 19:21:47

Android App在线程中创建handler的方法讲解_Android的相关文章

Android App在线程中创建handler的方法讲解

相关概念 1.Handler:可以看做是一个工具类,用来向消息队列中插入消息的; 2.Thread:所有与Handler相关的功能都是与Thread密不可分的,Handler会与创建时所在的线程绑定; 3.Message:消息; 4.MessageQueue:消息队列,对消息进行管理,实现了一个Message链表; 5.Looper:消息循环,从MessageQueue中取出Message进行处理: 6.HandlerThread:继承Thread,实例化时自动创建Looper对象,实现一个消息

Android App在ViewPager中使用Fragment的实例讲解_Android

据说Android最推荐的是在ViewPager中使用FragMent,即ViewPager中的页面不像前面那样用LayoutInflater直接从布局文件加载,而是一个个Fragment.注意这里的Fragment 是android.support.v4.view包里的Fragment,而不是android.app包里的Fragment. 使用v4包里的Fragment的Activity必须继承自FragmentActivity. 其实使用Fragment与前面不使用Fragment非常类似:

background-无法在线程中创建handler

问题描述 无法在线程中创建handler 错误: logUser("An error happend while creating graph:"+ getErrorMessage()); getErrorMessage()无法在线程中创建handler,线程没有调用Looper.prepare(),而logUser 是用来显示toast信息的函数. void prepareGraph() { logUser("loading graph (" + Helper.V

Android App在ViewPager中使用Fragment的实例讲解

据说Android最推荐的是在ViewPager中使用FragMent,即ViewPager中的页面不像前面那样用LayoutInflater直接从布局文件加载,而是一个个Fragment.注意这里的Fragment 是android.support.v4.view包里的Fragment,而不是android.app包里的Fragment. 使用v4包里的Fragment的Activity必须继承自FragmentActivity. 其实使用Fragment与前面不使用Fragment非常类似:

【Android开发】线程与消息处理-Handler消息传递机制之Looper

在前面已经介绍了在Android中如何创建.开启.休眠和中断线程.不过,此时并没有在新创建的子线程中对UI界面上的内容进行操作,如果应用前面介绍的方法对UI界面进行操作,将抛出异常. 为此,Android中引入了Handler消息传递机制,来实现在新创建的线程中操作UI界面.下面将对Handler消息传递机制进行介绍. 1.循环者Looper介绍 在介绍Looper之前,需要先了解一下MessageQueue的概念.在Android中,一个线程对应一个Looper对象,而一个Looper对象又对

handler-Android。在无限循环的线程中创建Message对象,无限出现GC调用。

问题描述 Android.在无限循环的线程中创建Message对象,无限出现GC调用. 我在Android开发中.开启了一个线程,这个线程是无限循环的.并且在这个线程里,我通过创建Handle的Message对象,然后handler.sendMessage(msg).可是这样一来,LOGCat上就一直出现GC_CONCURRENT.请问我该怎么修改代码,或者用哪种方式才能即实现功能,又能减少GC的调用.具体代码如下://线程private class getData_thread extends

Android APP之WebView校验SSL证书的方法

Android系统的碎片化很严重,并且手机日期不正确.手机根证书异常.com.google.android.webview BUG等各种原因,都会导致WebViewClient无法访问HTTPS站点.SSL错误的处理方式十分关键,如果处理不当,可能导致中间人攻击,黑客窃听数据,进而引发安全事故. 严谨地处理onReceivedSslError尤为重要.请参考以下代码,原理是:如果webview报告SSL错误,程序将会对服务器证书进行强校验,如果服务器传入证书的指纹(sha256)与记录值一致,说

Java线程中start和run方法全面解析_java

自定义线程两种方法 自定义一个runnable接口的实现类,然后构造一个thread,即对thread传入一个runnable接口类. new一个thread或者写个thread子类,覆盖它的run方法.(new 一个thread并覆盖run方法实际上是匿名内部类的一种方式) 示例代码 public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { System.

Android App更改应用的图标的实现方法

Android App更改应用的图标的实现方法 一般情况下,我们App图标在Androidmanifest.xml中设置,通过Application android:icon属性指定,写法如下: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package=&q