首页 > 其他分享 >Android handler src track

Android handler src track

时间:2023-05-23 16:05:52浏览次数:40  
标签:src Thread track sThreadLocal handler Looper new Android mQueue


HandlerThread 是 真正干活的,本身就是一个Thread:

HandlerThread extends Thread

主要比普通的Thread多了一个Looper,而hanlderThread的run函数其实很简单:

@Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();               这一步就生了该Thread自己的Looper
        synchronized (this) {
            mLooper = Looper.myLooper(); mLooper其实一个ThreadLocal变量,每个Thread有自己的一个Looper
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();        在得到Looper以后,就开始无限loop了,直到被要求结束,才会结束run函数,而HandlerThread的生命也结束。
        mTid = -1;
    }



Looper中有一个static final 的 ThreadLocal:

static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();   这就意味着每个Thread 都有一个自己的sThreadLocal

而sThreadLocal中的Looper是在prepare()时生成的:

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

Looper中有

    final MessageQueue mQueue;    就是存放要执行的任务, 在构造时生成: mQueue = new MessageQueue(quitAllowed);
    final Thread mThread;                 记录运行自己的Thread, 在构造的时候就绑定了: mThread = Thread.currentThread();

Looper的quit其实就是mQueue的quit:

public void quit() {
        mQueue.quit(false);
    }



可以看到,真正干活的所有成员就是handlerThread,

而Handler的作用在这里类似于一个对Looper的代理和封装:

首先,handler的构造需要一个Looper, 如果不制定Looper,那么就用当前线程的Looper,因此,在一个Thread使用Handler的前提是该线程的Looper要存在。

public Handler(Callback callback, boolean async) {
........................................................

        mLooper = Looper.myLooper();
        if (mLooper == null) { 如果当前Thread还没有自己的Looper,那么就 RuntimeException。
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }



而handler基本做的所有关键工作,就是对Looper操作的再封装罢了:

比如,post:

post(Runnable r) -> sendMessageDelayed(getPostMessage(r), 0); -> sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis)

-> enqueueMessage(queue, msg, uptimeMillis) -> queue.enqueueMessage(msg, uptimeMillis)

这里的queue,就是Looper的MessageQueue。


Looper提供了 loop()<处理任务的方法> 和 MessageQueue<存放待运行任务的队列> , handlerThread 则负责实际的执行<苦力>

而handler则是对上面这个机制的简便性包装.

handler的封装性也体现在对于其enqueueMessage(...)中,这一步会把要enqueue的Message的target设置为handler自己,这样在后面的Looper的loop()中处理Message时,会直接调用msg.target.dispatchMessage(msg), 这样就实现了handler enqueue的Message最后由handler自己来处理.

标签:src,Thread,track,sThreadLocal,handler,Looper,new,Android,mQueue
From: https://blog.51cto.com/u_9420214/6332937

相关文章

  • Android开发 UsageStatsManager应用使用情况管理
    前言  UsageStatsManager是用来知晓,设备中应用的使用情况的管理。它能给我们提供应用的进入前台动作与时间戳、进入后台的动作与时间戳、上次的使用时间、使用总时长等等信息。此功能在原生的设置-应用-使用统计中有所展示。所需权限<uses-permissionandroid:name="android.......
  • Android平台GB28181设备接入模块如何实现实时视频和本地录像双码流编码
    ​技术背景我们在做Android平台GB28181设备接入模块的时候,遇到这样的场景,比如执法记录仪或智慧工地等场景下,由于GB28181设备接入模块,注册到国标平台后,平时只是心跳保持,或还有实时位置订阅,查看视频的时候,是按需看,而且有时候,网络环境并不是太好,所以,催生了这样一个诉求:部分开发者希......
  • 修改Android 触摸提示音及音量大小
    一、修改代码提高系统的音量。代码路径:base/services/core/java/com/android/server/audio/AudioService.javaprivatestaticint[]MAX_STREAM_VOLUME=newint[]{5,//STREAM_VOICE_CALL7,//STREAM_SYSTEM7,//STREAM_RING15......
  • Git拉取代码报错:Can't Update No tracked branch configured for branch dev or the b
    错误: 解决方法:第一步:gitpullorigin(远程仓库名称)develop(远程分支名称)--allow-unrelated-histories第二步:gitbranch--set-upstream-toorigin(远程仓库名称)/develop(远程分支名称)dev(本地分支名称)显示如下则为成功,可正常拉取代码 ......
  • Android利用activity启动模式退出整个应用
    前面我们来先看一下目前网上提供的几种方案:1.退出单个activity1)、获取当前进程的id,杀死该进程。android.os.Process.killProcess(android.os.Process.myPid())2)、终止当前正在运行的Java虚拟机方法。System.exit(0); 3)、finish();4)、杀包方式。......
  • android 使用多个Intent 进行activity跳转 而没有finish的情况,如何直接退出系统
    <:section><!--列表视图页显示缩略图和文章摘要--><!--文章视图页显示全部内容--><!--如果有内容,显示内容-->就是N个Activity跳转没finish();最后一个Activity单击事件如何推出整个程序?很简单:只要在最后一个需要finish掉之前所有的avtivity的Intent上加上这样一句话......
  • android-card-slide-panel模仿探探首页卡片左右滑动效果,滑动流畅,卡片view无限重生...
    android-card-slide-panel类别: 图像(Image)打分: ★★★★★更新: 2015-12-0312:37大小: 10003kb开发环境: AndroidStudio浏览: 913次下载: 213次项目地址: https://github.com/xmuSistone/android-card-slide-panel图片,手势下载 收藏xmuSistone......
  • Android ContentProvider详解
    一.Android四大组件Android四大组件是Activity,Service,ContentProvider,BroadcastReceiver。Activity作为程序界面,直接与用户交互Service运行在后台,没有界面,完成特定的功能ContentProvider维护应用数据,方便应用本身或其它应用访问BroadcastReceiver提供异步广播消息接收机制,......
  • StackOverView又一个Android 5.0 任务管理器控件。这次这个比上次那个(MaterialRecents
    StackOverView视图布局(ViewLayout)★★★★★2015-09-2120:21147kbAndroidStudio1075次165次https://github.com/Bossyao168/StackOverView卡片,任务下载 收藏 Bossyao168 / StackOverViewacustomwidgetofandroid,liketaskmanagerofandr......
  • 【Android】Uri、UriMatcher、ContentUris详解
     1.Uri通用资源标志符(UniversalResourceIdentifier,简称"URI")。Uri代表要操作的数据,Android上可用的每种资源-图像、视频片段等都可以用Uri来表示。 URI一般由三部分组成:访问资源的命名机制。 存放资源的主机名。 资源自身的名称,由路径表示。      Android的Uri由以......