result = temp; //6
}
return result;
}
3、通过createViewFromTag创建根view,此方法调用链如下所示;注释1处是第一次创建view;注释2和注释3最终都会调用到注释3处的方法;注释1是一种情况,注释3是另一种情况,我们分别讨论一下;
private View createViewFromTag(View parent, String name, Context context, AttributeSet attrs) {
return createViewFromTag(parent, name, context, attrs, false);
}
View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,
boolean ignoreThemeAttr) {
View view = tryCreateView(parent, name, context, attrs); //1
if (view == null) {
final Object lastContext = mConstructorArgs[0];
mConstructorArgs[0] = context;
try {
if (-1 == name.indexOf(‘.’)) {
view = onCreateView(context, parent, name, attrs); //2
} else {
view = createView(context, name, null, attrs); //3
}
}
}
return view;
}
3-1 tryCreateView
第一种情况tryCreateView方法如下所示,如果mFactory2不为空,会通过注释1处mFactory2的onCreateView方法创建view;如果mFactory不为空,会通过注释2处mFactory的onCreateView创建view;那么这两个factory是什么呢?如注释3和注释4所示,Factory是一个单方法的接口,Factory2继承自Factory,重载了一个onCreateView方法;这两个变量初始都为空,因此我们开发者可以实现这两个接口,然后赋值给这两个变量,这样就会优先通过我们设置的方法加载view了;
public final View tryCreateView(@Nullable View parent, @NonNull String name,
@NonNull Context context,
@NonNull AttributeSet attrs) {
View view;
if (mFactory2 != null) {
view = mFactory2.onCreateView(parent, name, context, attrs); //1
} else if (mFactory != null) {
view = mFactory.onCreateView(name, context, attrs); //2
} else {
view = null;
}
return view;
}
private Factory mFactory; //3
private Factory2 mFactory2; //4
public interface Factory {
View onCreateView(@NonNull String name, @NonNull Context context,
@NonNull AttributeSet attrs);
}
public interface Factory2 extends Factory {
View onCreateView(@Nullable View parent, @NonNull String name,
@NonNull Context context, @NonNull AttributeSet attrs);
}
3-2 createView
因为系统并没有给mFactory和mFactory2赋值,因此会走到createView方法;方法代码如下所示,注释1处首先从sConstructorMap获取构造方法,第一次肯定为空;然后走到注释2处,通过反射获得构造方法,mConstructorSignature这个参数代表的是两个参数的构造方法,因此返回的就是带两个参数的构造方法;接着在注释3处将构造方法放入sConstructorMap中;最后在注释4处通过newInstance方法获取view实例并返回;
public final View createView(@NonNull Context viewContext, @NonNull String name,
@Nullable String prefix, @Nullable AttributeSet attrs)
throws ClassNotFoundException, InflateException {
Constructor<? extends View> constructor = sConstructorMap.get(name); //1
if (constructor == null) {
constructor = clazz.getConstructor(mConstructorSignature); //2
constructor.setAccessible(true);
sConstructorMap.put(name, constructor); //3
}
Object lastContext = mConstructorArgs[0];
mConstructorArgs[0] = viewContext;
Object[] args = mConstructorArgs;
args[1] = attrs;
final View view = constructor.newInstance(args); //4
return view;
}
三、AndroidX的AppCompatActivity源码变化
1、当我们的Activity继承自AppCompatActivity时,setContentView方法会调用到AppCompatActivity的setContentView;因此最终调用的是AppCompatDelegateImpl的setContentView;
AppCompatActivity – setContentView
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
AppCompatActivity – getDelegate
public AppCompatDelegate getDelegate() {
if (mDelegate == null) {
mDelegate = AppCompatDelegate.create(this, this);
}
return mDelegate;
}
AppCompatDelegate – create
public static AppCompatDelegate create(@NonNull Activity activity,
@Nullable AppCompatCallback callback) {
return new AppCompatDelegateImpl(activity, callback);
}
2、AppCompatDelegateImpl的setContentView方法如下所示,注释1处的ensureSubDecor()最终还是会调用到installDecor方法;注释2处用于获得contentParent;注释3处用于将我们的布局添加到contentParent中;
public void setContentView(int resId) {
ensureSubDecor(); //1
ViewGroup contentParent = mSubDecor.findViewById(android.R.id.content); //2
contentParent.removeAllViews();
LayoutInflater.from(mContext).inflate(resId, contentParent);//3
mAppCompatWindowCallback.getWrapped().onContentChanged();
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
总结
可以看出,笔者的工作学习模式便是由以下 「六个要点」 组成:
❝ 多层次的工作/学习计划 + 番茄工作法 + 定额工作法 + 批处理 + 多任务并行 + 图层工作法❞
希望大家能将这些要点融入自己的工作学习当中,我相信一定会工作与学习地更富有成效。
下面是我学习用到的一些书籍学习导图,以及系统的学习资料。每一个知识点,都有对应的导图,学习的资料,视频,面试题目。
**如:我需要学习 **Flutter的知识。(大家可以参考我的学习方法)
- Flutter 的思维导图(无论学习什么,有学习路线都会事半功倍)
- Flutter进阶学习全套手册
- Flutter进阶学习全套视频
大概就上面这几个步骤,这样学习不仅高效,而且能系统的学习新的知识。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
面这几个步骤,这样学习不仅高效,而且能系统的学习新的知识。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-9A60ger8-1712695861208)]