Handler(原理) HandlerThread 轻松实现异步功能

阅读: 评论:0

Handler(原理) HandlerThread 轻松实现异步功能

Handler(原理) HandlerThread 轻松实现异步功能

上文说道Handler可以与任意线程绑定,这点可以帮助我们很轻松就是想异步工能


见如下代码,

public class MainActivity extends Activity {private static final String TAG = "Handler_demo";

    private  Handler myHandler;

    class MyThread extends  Thread {public  Handler handler ;
        public Looper looper;


        public void run(){Looper.prepare();

            looper = Looper();

            handler = new Handler(){@Override
                public void handleMessage(Message msg) {Log.e(TAG, "当前线程:" + Thread.currentThread());
                }};
            Looper.loop();


        }}@Override
    protected void onCreate(Bundle savedInstanceState) {Create(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyThread mt = new MyThread();
        mt.start();
        
        myHandler = new Handler(mt.looper){@Override
            public void handleMessage(Message msg) {Log.e(TAG, "Run IN 线程:" + Thread.currentThread());
            }};

        myHandler.sendEmptyMessage(0);

    }}


运行后发现包以下异常


09-27 22:41:50.577    1608-1608/com.liaoli.handleexample E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.liaoli.handleexample/com.liaoli.handleexample.MainActivity}: java.lang.NullPointerException
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
            at android.app.ActivityThread.access$600(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at flect.Method.invokeNative(Native Method)
            at flect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at com.liaoli.Create(MainActivity.java:52)
            at android.app.Activity.performCreate(Activity.java:5133)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
            at android.app.ActivityThread.access$600(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at flect.Method.invokeNative(Native Method)
            at flect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)

报异常的为

myHandler = new Handler(mt.looper){
这一行,也就是mt.looper为空了,这说明子线成还未来得及创建Looper实例,

此时取出来的肯定为空啊,针对这种情况,android为我们提供了一种解决方案,

提供了一个类,

public class HandlerThread extends Thread 

他是一个线程类,下面看一个简单的例子:

package com.liaoli.handlerthread_demo;

import android.app.Activity;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.Bundle;
import android.util.Log;


public class MainActivity extends Activity {private static final String TAG = "MainActivity";
    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {Create(savedInstanceState);
        setContentView(R.layout.activity_main);


        HandlerThread  ht = new HandlerThread("my HandlerThread");

        ht.start();

        handler = new Looper()){@Override
            public void handleMessage(Message msg) {Log.e(TAG, "Run IN 线程:" + Thread.currentThread());
            }};


        handler.sendEmptyMessage(0);
    }}
运行后打印:

09-27 23:07:09.237  11939-11956/com.liaoli.handlerthread_demo E/MainActivity﹕ Run IN 线程:Thread[my HandlerThread,5,main]

my HandlerThread 是我们给这个HandlerThread线程的名字,这个HandlerThread的run 方法中会去创建一个与此线程绑定的Looper,


@Override
public void run() {mTid = Tid();
    Looper.prepare();
    synchronized (this) {mLooper = Looper();
        notifyAll();
    }Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();
    mTid = -1;
}

此时并没有报空指针,那么,他是怎么做到的呢?我们看HandlerThread的


/**
 * This method returns the Looper associated with this thread. If this thread not been started
 * or for any reason is isAlive() returns false, this method will return null. If this thread 
 * has been started, this method will block until the looper has been initialized.  
 * @return The looper.
 */
public Looper getLooper() {if (!isAlive()) {return null;
    }// If the thread has been started, wait until the looper has been created.
    synchronized (this) {while (isAlive() && mLooper == null) {try {wait();
            } catch (InterruptedException e) {}}}return mLooper;
}
方法,他首先会取判断线程自己是不是活的,然后判断mLooper是否为null ,如果为空就wait(),也就是说为空就不会往下走了,器run方法中当mLooper 创建后,会取唤醒这个方

   synchronized (this) {mLooper = Looper();
        notifyAll();
    }

法,继续往下走,所以,就保证了我们在创建

 handler = new Looper()){
时,不会出现空指针的情形。


我们可一同过HandlerThread很轻松就实现一部操作,此时我们的Handler是与HandlerThread这个子线程绑定的,所以这个handler的所发送的消息都将在这个子线程中进行处理

。所以此时我们就可一将一些耗时的操作放在这个Handler 的handleMessage(Message msg)方法中进行处理。











本文发布于:2024-01-31 00:53:01,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170663368924118.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:原理   轻松   功能   Handler   HandlerThread
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23