2024年Android最新【面试总结】Android-开发者值得深入思考的几个面试问答分享,2024年最新面试字节跳动两轮后被完虐

资源分享

  • 最新大厂面试专题

这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等

  • 对应导图的Android高级工程师进阶系统学习视频
    最近热门的,NDK,热修复,MVVM,源码等一系列系统学习视频都有!

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

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

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

childrenCount, i, customOrder);
final View child = getAndVerifyPreorderedView(
preorderedList, children, childIndex);

}

如果传进去的preorderedList不为空,那么就会直接从它里面去取。

####preorderedList怎么来?

通过调用buildOrderedChildList方法获取的。

buildOrderedChildList方法是怎么样的?

ArrayList buildOrderedChildList() {
final int childrenCount = mChildrenCount;
if (childrenCount <= 1 || !hasChildWithZ()) return null;

if (mPreSortedChildren == null) {
mPreSortedChildren = new ArrayList<>(childrenCount);
} else {
// callers should clear, so clear shouldn’t be necessary, but for safety…
mPreSortedChildren.clear();
mPreSortedChildren.ensureCapacity(childrenCount);
}

final boolean customOrder = isChildrenDrawingOrderEnabled();
for (int i = 0; i < childrenCount; i++) {
// add next child (in child order) to end of list
final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
final View nextChild = mChildren[childIndex];
final float currentZ = nextChild.getZ();

// insert ahead of any Views with greater Z
int insertIndex = i;
while (insertIndex > 0 && mPreSortedChildren.get(insertIndex - 1).getZ() > currentZ) {
insertIndex–;
}
mPreSortedChildren.add(insertIndex, nextChild);
}
return mPreSortedChildren;
}

它里面是通过一个getAndVerifyPreorderedIndex方法来获取对应的子VIew索引,这个方法要传进去一个叫customOrder的boolean。

这个customOrder,看名字可以知道,是自定义顺序的意思,如果它为true的话,接着会通过getChildDrawingOrder(int childCount, int i)方法来获取对应的索引,而且,这个方法是protected的,所以我们可以通过重写这个方法并根据参数"i"来决定返回哪一个View所对应的索引,从而改变分发的顺序。

protected int getChildDrawingOrder(int childCount, int i) {
return i;
}

那这个customOrder,什么时候为true呢?

在buildOrderedChildList方法里可以看到这么一句:

final boolean customOrder = isChildrenDrawingOrderEnabled();

emmmm,也就是说,如果要自定义这个顺序的话,还需要调用setChildrenDrawingOrderEnabled(true)来开启。

重新捋一捋流程:

1. setChildrenDrawingOrderEnabled(true)来开启自定义顺序;
2. 重写getChildDrawingOrder方法来决定什么时候要返回哪个子View;

###2. AppCompatTextView 与 TextView 有什么区别?

1. compat库是如何将TextView替换为AppCompatTextVew的?
2. 为什么要进行替换?
3. 根据替换相关原理,我们可以做哪些事情?

####先从第二问开始吧:

AppCompatTextView继承自TextView,是对TextView的一种扩展,因为在5.0中首次推出了MaterialDesign这种设计风格。

但是众所周知的,5.0推出不可能所有的设备全都一下子更新到最新版本,为了在早期版本上实现新的功能(这些新功能比如从源码注释中解读到比如backgroundTint属性,根据文本内容自适应大小等).

即为了新特性同样可以兼容老版本,framework在创建TextView实例的时候,自动帮我们进行了替换。

其它的AppCompatXXX与XXX的关系也是如此。

####第一问:

然后第一问,如何完成替换的,我们这里只拿最直观的流程举例,且尽可能的简化源码过程,在讨论这个问题之前,先了解几个预备知识:

View是怎么被解析创建出来的:

**1.LayoutInflater:**将布局XML文件实例化为其对应的View对象,我们在Activity中通过setContentView传入一个Layout的资源文件id,最终该方法最终会调用到PhoneWindow的setContentView方法,这个方法里面有调用到

mLayoutInflater.inflate(layoutResID, mContentParent);

2.inflate方法,该方法的作用是将指定的XML文件填充到View的层次结构中去,最终无论通过什么途径调用到inflate方法,都会走到三个参数的重载方法这里:

return inflate(parser, root, attachToRoot);

parser你可以认为持有将Layout.XML解析后的数据。后两个参数的意义如下:

1. root为null,attchToRoot无意义,inflate返回的是当前XML对应的根布局。
2. root不为null且attachToRoot为true,则整个XML对应的布局就设置了根布局是root。
3. root不为null且attachToRoot为false,则会将root的layoutParames设置给当前XML的布局。

知道了LayoutInflate.inflate做了什么,再往下,inflate中会调用createViewFromTag,从方法名就能知道,继续往下走,我们离答案越来越近了。

createViewFromTag做的事情非常有意思:

先看到787行这个if-else,条件是name中有没有"."字符,如果有我们会执行onCreateView,如果没有会执行createView。

####name啥时候有点?

自定义控件的时候。

当是系统控件的时候,createView会有一个填充了第二个参数的调用:

createView(name, “android.view.”, attrs);补上了View控件的全路径名,而自定义控件则不需要,因为传入的name就是一个全路径名。

####为什么要全路径名?

因为View控件对象的创建是通过反射来实现的:

clazz = mContext.getClassLoader().loadClass(
prefix != null ? (prefix + name) : name).asSubclass(View.class);

constructor = clazz.getConstructor(mConstructorSignature);
constructor.setAccessible(true);
sConstructorMap.put(name, constructor);
// …
args[1] = attrs;
final View view = constructor.newInstance(args);

下面对这几步做一个总结:

XML中保存了ViewTree的结构和View的相关标签信息(包括View的类型和一些属性值),然后这些信息会在后面通过反射的方式(如果没有Factory2和Factory的话)创建实例对象,如果创建的是ViewGroup,则会对它的子View遍历重复创建步骤,创建完View对象后,会add到对应的ViewGroup中。

其中相关方法的调用流程是:

inflate->rInflate->createViewFromTag->createView。

好像还是没有看到替换?

还是上一张图,我们只解释了后半部分,没有解释前半部分,那么什么是Factory?

继续往下看:

createViewFromTag中会先判断有没有Factory或者Factory2的对象,如果有,则调用Factory的onCreateView方法。

这两个类都是接口,其中Factory2是Factory的子接口,都只有唯一一个onCreateView方法。

不同之处在于Factory2的onCreateView方法传入了parentView。

该方法的作用就是你可以借助它来改造XML中已经存在了的Tag的值。所以Factory2可以达到改造parentView的目的。

但是我们在日常中根本就没有任何地方接触到了Factory(2)呀,那么它是不是就直接是null呢?

到这里又是一番源码调来调去,为了便于理解,只需要知道,这个东西(Factory2),在最开始AppCompatActivity(为了兼容低版本,我们现在Activity默认都是继承自它)中的onCreate方法中就已经通过层层调用被设置好了。

既然现在Factory2不为空,那么就应该去走它的onCreateView方法了,这里又是层层调用,最终来到了AppCompatViewInflater**** 的 createView 方法:

答案就在这里:

如果创建的是非兼容控件(系统控件那么多,实现兼容的只是常用的一些控件),那么就会是143行,在146中通过反射创建View对象。

啰里啰唆扯了一大堆,还是没回答第一个问题:

最后,面试前该准备哪些资源复习?

其实客户端开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

这里再分享一下我面试期间的复习路线:(以下体系的复习资料是我从各路大佬收集整理好的)

《Android开发七大模块核心知识笔记》

面试字节两轮后被完虐,字节面试官给你的技术面试指南,请查收

面试字节两轮后被完虐,字节面试官给你的技术面试指南,请查收

《960全网最全Android开发笔记》

面试字节两轮后被完虐,字节面试官给你的技术面试指南,请查收

《379页Android开发面试宝典》

历时半年,我们整理了这份市面上最全面的安卓面试题解析大全
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

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

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

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

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

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值