2024年Android最全Android知识笔记:记录 2 个 “容易误解” 的Android 知识点,2024年最新Android面试经历

最后,如果大伙有什么好的学习方法或建议欢迎大家在评论中积极留言哈,希望大家能够共同学习、共同努力、共同进步。

小编在这里祝小伙伴们在未来的日子里都可以 升职加薪,当上总经理,出任CEO,迎娶白富美,走上人生巅峰!!

不论遇到什么困难,都不应该成为我们放弃的理由!

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢。

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

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

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

if (stage != null) {

//关键点:上面决定将事件派发到那个InputStage中处理

stage.deliver(q);

} else {

finishInputEvent(q);

}

}

ViewRootImpl.ViewPostImeInputStage

前面事件会派发到ViewRootImpl.ViewPostImeInputStage中处理,它的父类InputStage.deliver()方法会调用apply()来处理Touch事件:

@Override

protected int onProcess(QueuedInputEvent q) {

if (q.mEvent instanceof KeyEvent) {

return processKeyEvent(q);

} else {

final int source = q.mEvent.getSource();

if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {

//关键点:执行分发touch事件

return processPointerEvent(q);

} else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {

return processTrackballEvent(q);

} else {

return processGenericMotionEvent(q);

}

}

}

private int processPointerEvent(QueuedInputEvent q) {

final MotionEvent event = (MotionEvent)q.mEvent;

//关键点:mView分发Touch事件,mView就是DecorView

boolean handled = mView.dispatchPointerEvent(event);

maybeUpdatePointerIcon(event);

maybeUpdateTooltip(event);

}

DecorView

如果你熟悉安卓的Window,Activity和Dialog对应的ViewRootImpl成员mView就是DecorView,View的dispatchPointerEvent()代码如下:

//View.java

public final boolean dispatchPointerEvent(MotionEvent event) {

if (event.isTouchEvent()) {

//分发Touch事件

return dispatchTouchEvent(event);

} else {

return dispatchGenericMotionEvent(event);

}

}

因为DecorView继承FrameLayout,上面所以会调用DecorView的dispatchTouchEvent():

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

final Window.Callback cb = mWindow.getCallback();

return cb != null && !mWindow.isDestroyed() && mFeatureId < 0

? cb.dispatchTouchEvent(ev) : super.dispatchTouchEvent(ev);

}

上面Window.Callback都被Activity和Dialog实现,所以变量cb可能就是Activity和Dialog。

Activity

当上面cb是Activity时,执行Activity的dispatchTouchEvent():

public boolean dispatchTouchEvent(MotionEvent ev) {

if (ev.getAction() == MotionEvent.ACTION_DOWN) {

onUserInteraction();

}

if (getWindow().superDispatchTouchEvent(ev)) {//关键点:getWindow().superDispatchTouchEvent(ev)

return true;

}

return onTouchEvent(ev);

}

如果你熟悉安卓的Window,Activity的getWindow()拿到的就是PhoneWindow,下面是PhoneWindow的代码:

//PhoneWindow.java

@Override

public boolean superDispatchTouchEvent(MotionEvent event) {

//调用DecorView的superDispatchTouchEvent

return mDecor.superDispatchTouchEvent(event);

}

下面是DecorView.superDispatchTouchEvent()代码:

//DecorView.java

public boolean superDispatchTouchEvent(MotionEvent event) {

//调用ViewGroup的dispatchTouchEvent()开始我们常见的分发Touch事件

return super.dispatchTouchEvent(event);

}

流程图

答:为什么要DecorView -> Activity -> PhoneWindow -> DecorView传递事件?

解耦!

ViewRootImpl并不知道有Activity这种东西存在!它只是持有了DecorView。

所以,不能直接把触摸事件送到Activity.dispatchTouchEvent();

那么,既然触摸事件已经到了Activity.dispatchTouchEvent()中了,为什么不直接分发给DecorView,而是要通过PhoneWindow来间接发送呢?

因为Activity不知道有DecorView!但是,Activity持有PhoneWindow ,而PhoneWindow当然知道自己的窗口里有些什么了,所以能够把事件派发给DecorView。

在Android中,Activity并不知道自己的Window中有些什么,这样耦合性就很低了。

我们换一个Window试试?

不管Window里面的内容如何,只要Window仍然符合Activity制定的标准,那么它就能在Activity中很好的工作。当然,这就是解耦所带来的扩展性的好处。

以上回答感谢:蔡徐坤打篮球。


2. RecyclerView卡片中持有的资源,到底该什么时候释放?

之前我们讨论过 View的onAttachedToWindow ,onDetachedFromWindow 调用时机 。

这个机制在RecyclerView卡片中还适用吗?

例如我们在RecyclerView的Item的onBindViewHolder时,利用一个CountDownTimer去做一个倒计时显示 / 或者是有一个属性动画效果?

到底在什么时候可以cancel掉这个倒计时/ 动画,而不影响功能了(滑动到用户可见范围内,倒计时/动画 运作正常)?

有什么方法可以和onBindViewHolder 对应吗?就像onAttachedToWindow ,onDetachedFromWindow这样 。

答:

onAttachedToWindow和onDetachedFromWindow在RecyclerView中还适用吗?

在RecyclerView中,Item的这两个方法分别会在【首次出现】和【完全滑出屏幕】(即在屏幕中完全不可见)时回调(在Adapter中也可以重写同名方法,用来监听ViewHolder的出现和消失)。

至于说适不适用,还是看具体需求,比如列表中的视频播放,在onDetachedFromWindow回调时暂停/停止还是合理的。

但是像题目说的倒计时和属性动画效果,就不合适了,为什么呢?

我们先粗略地温习一下RecyclerView的回收机制:

RecyclerView在布局(自然滑动其实也是反复布局子View)时,会回收一些符合条件的ViewHolder,它会根据ViewHolder的状态来决定临时存放在哪个地方,且把这些临时存放ViewHolder的集合看作两种:

不需要经过onBindViewHolder能直接重用的(mAttachedScrap、mCachedViews);

需要经过onBindViewHolder重新绑定数据的(mRecyclerPool.mScrap);

mAttachedScrap,正常情况下,它会在RecyclerView每次布局时都用到:在布局子View时,会把全部子View所属的Holder,都临时放里面,计算好了每个子View的新位置后,会一个个从mAttachedScrap中取出来,当然了不一定是全部都会取出来的,因为可能本次布局,一些旧Item已经完全滑出屏幕了。

那么,这些留在mAttachedScrap中没有被取出来的ViewHolder会怎么样呢?

正常情况下,它们会被扔到mCachedViews里面去(注意从mCachedViews中取出来时也是不用重新绑定数据的,即不会经过onBindViewHolder方法)。

刚刚说过,当Item被完全滑出屏幕时,Adapter的onDetachedFromWindow和该Item的onDetachedFromWindow会被回调,也就是说,当onDetachedFromWindow被回调时,ViewHolder并没有真正被回收!如果这时候把倒计时/动画取消掉了,那么在它们再次出现在屏幕中的时候,就不会动了,因为是直接重用,不会重新绑定数据的。

那应该在什么时候取消?

Adapter中有个onViewRecycled方法,看名字就知道是当Item被回收后回调的。。。

没错了,这个方法回调时,表示这个Holder已经被扔进mRecyclerPool.mScrap里了,也就是再次取出的时候会经过onBindViewHolder方法重新绑定数据。

倒计时/动画在这里取消的话,是完全没问题的(但记得保存当前进度,以便下次恢复)。

所以与onBindViewHolder对应的方法,就是这个onViewRecycled了。

最后,以上的阐述没办法保证一定是非常严谨的,所以请抱着学习以及批判的态度学习,有问题就指出,争取把一个个技术点尽可能搞清楚,大家一起进步。

最后

写在最后

本次我的分享也接近尾声了,感谢你们在百忙中花上一下午来这里聆听我的宣讲,希望在接下来的日子,我们共同成长,一起进步!!!

最后放上一个大概的Android学习方向及思路(详细的内容太多了~),提供给大家:

对于程序员来说,要学习的知识内容、技术有太多太多,这里就先放上一部分,其他的内容有机会在后面的文章向大家呈现出来,不过我自己所有的学习资料都整理成了一个文档,一直在不断学习,希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!

Android架构师之路很漫长,一起共勉吧!

如果你觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢。

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

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

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

满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!**

Android架构师之路很漫长,一起共勉吧!

如果你觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢。

[外链图片转存中…(img-ObOnGtKG-1715617914759)]

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

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

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

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值