2024年Android最新【面试专题】2024年大厂 Handler 面试题集合,2024年最新android界面开发经典书籍

最后看一下学习需要的所有知识点的思维导图。在刚刚那份学习笔记里包含了下面知识点所有内容!文章里已经展示了部分!如果你正愁这块不知道如何学习或者想提升学习这块知识的学习效率,那么这份学习笔记绝对是你的秘密武器!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

Looper死循环为什么不会导致应用卡死?


Handler是native层的阻塞、唤醒(nativePollOnce、nativeWake)机制,应用卡死那是ANR(这边可以展开说一下 ANR),有条件的可以说一下 Linux 底层的消息机制(这个绝对是加分项)。

如何保证线程和Looper的一对一关系的?


static final ThreadLocal sThreadLocal = new ThreadLocal();

Looper.prepare()的时候通过sThreadLocal.set()塞值,Looper.myLooper()获取的时候通过sThreadLocal.get()取值。ThreadLocal内部是key、value的Map结构,key是线程、value是存储的值(这边存储的就是Looper),所以线程和Looper一对一。

这边可能会被问,sThreadLocal为什么是static的?这边答案我不太确定,我面试的时候是答的只需要装载一次,减少对象创建开销;线程内所有操作共享。有知道为什么的大佬可以评论区教教大家。

handler是如何发送延迟消息的?


MessageQueue -> next函数分拣消息的时候,会根据msg.when和当前时间计算出一个nextPollTimeoutMillis值,这个值就是控制消息延迟的。

nextPollTimeoutMillis决定了堵塞与否,以及堵塞的时间,三种情况:

等于0时,不堵塞,立即返回,Looper第一次处理消息,有一个消息处理完 ;

大于0时,最⻓堵塞等待时间,期间有新消息进来,可能会了立即返回(立即执行);

等于-1时,无消息时,会一直堵塞;

阻塞内部就是通过native函数nativePollOnce、nativeWake来实现的,这边可以展开说,说清楚了你就是P7大佬了,我反正是不会······(但是这个nativePollOnce,面试官必会问你清不清楚实现原理,应该是想考察你的深度,还是建议查阅了解下)

如果想要在子线程中new Handler要做些什么准备?


简单来说就是在子线程里面初始化Looper:prepare后loop,然后构造handler的时候传入对应的子线程Looper对象。

Thread thread = new Thread(new Runnable() {

Looper looper;

@Override

public void run() {

// Log.d(TAG, "click2: " + Thread.currentThread().getName());

Looper.prepare();

looper =Looper.myLooper();

Looper.loop();

}

public Looper getLooper() {

return looper;

} });

thread.start();

Handler handler = new Handler(thread.getLooper());

上述代码可能会牵扯到一些多线程的问题,调用 thread.getLooper()的时候,此时的looper可能还没

有初始化。

这边需要引入HandlerThread的概念,这东西就是Android源码层对子线程handler的一个简单的封装:

@Override

public void run() {

mTid = Process.myTid();

Looper.prepare();

synchronized (this) {

mLooper = Looper.myLooper();

notifyAll();

}

Process.setThreadPriority(mPriority);

onLooperPrepared();

Looper.loop();

mTid = -1;

}

Handler内存泄露


这个问题不记得是哪家中厂问的了,只被问到过一次,低频考察题目(大厂估计都不屑于问这个了)。

匿名内部类持有外部Activity引用,导致内存泄漏。

如何监控handler中的消息?


这个是字节问的一个问题,我不是很清楚我回答的是不是面试官想要的。

Looper中有一个Api:setMessageLogging,会输出一个 Printer,用来打印每一条 message 消息。

如果有大佬有其他方案,欢迎评论区告知。

异步消息、同步屏障


这个也是必问题目。

线程的消息都是放到同一个MessageQueue里面,取消息的时候是互斥取消息(里面有大范围的synchronized代码块),而且只能从头部取消息,而添加消息是按照消息的执行的先后顺序进行的排序。如果有一个消息是需要立刻执行的,也是想要这个消息插队,那么就可以开启一个同步屏障,阻碍同步消息,只让异步消息通过,就是同步屏障的概念。

开启同步屏障:MessageQueue 的 postSyncBarrier()

要注意这个方法是hide方法,外部无法调用的,这个细节问题网易问过。顺带后面还问了如果我外部就是要发送一个异步消息怎么办?(不急,后边马上说)

postSyncBarrier()里面的Message 对象初始化的时候并没有给 target 赋值,因此, target == null。这样,一条target == null 的消息就进入了消息队列。

Message next()分拣消息的时候,如果发现消息队列开启同步屏障(即标识为msg.target == null),就会优先处理异步消息。

异步消息在源码中的应用


ViewRootImpl 的 scheduleTraversals()

void scheduleTraversals() {

if (!mTraversalScheduled) {

mTraversalScheduled = true;

//开启同步屏障

mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();

//发送异步消息

mChoreographer.postCallback(

Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);

}

}

如何外部发送一个异步消息


public Handler(boolean async)构造handler的时候选用对应的构造函数,那么通过这个handler发送的消息就都是异步的了,handler会自动给每个message添加setAsynchronous(true)。

message.setAsynchronous(true),但是这个方法需要 API 22。

IdleHandler

尾声

在我的博客上很多朋友都在给我留言,需要一些系统的面试高频题目。之前说过我的复习范围无非是个人技术博客还有整理的笔记,考虑到笔记是手写版不利于保存,所以打算重新整理并放到网上,时间原因这里先列出面试问题,题解详见:


展示学习笔记

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

2P-1715670852704)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值