LayoutInflater hook点
在Activity里执行setContentView或者inflate布局文件最终都会走到如下代码:

LayoutInflater.javaView createViewFromTag(View parent, String name, Context context, AttributeSet attrs,boolean ignoreThemeAttr) {...try {View view;if (mFactory2 != null) {//1 hook点 mFactory2优先view = mFactory2.onCreateView(parent, name, context, attrs);} else if (mFactory != null) {//2 hook点view = mFactory.onCreateView(name, context, attrs);} else {view = null;}if (view == null && mPrivateFactory != null) {view = mPrivateFactory.onCreateView(parent, name, context, attrs);}//如果fatory2、factory都返回null则进入函数体if (view == null) {final Object lastContext = mConstructorArgs[0];mConstructorArgs[0] = context;try {if (-1 == name.indexOf('.')) {//framework.jar里的View,即安卓原生View控件。 例如name是TextView、Button。 会执行createView(name, "android.view.", attrs);  即添加包名后执行createView函数view = onCreateView(parent, name, attrs);} else {//自定义View( 含support库里的View), name是包名+类名。通过反射实例化view = createView(name, null, attrs);}} finally {mConstructorArgs[0] = lastContext;}}return view;} catch (InflateException e) {throw e;} catch (ClassNotFoundException e) {}
}

通过代码得到结论, 在inflate时优先使用mFactory2和mFactory实例化, 如果都实例化失败时执行createView函数实例化View, 而实例化是用类反射的方式实现的,需要完整的包名和类名; 如果是安卓原生控件需要添加android.view前缀。

测试代码:

public class TestFragmentActivity extends Activity {private final String TAG = "brycegao/Main";@Override protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);LayoutInflaterCompat.setFactory2(getLayoutInflater(), new LayoutInflater.Factory2() {@Overridepublic View onCreateView(View parent, String name, Context context, AttributeSet attrs) {long startTime = System.currentTimeMillis();View view = null;try {//这里可以“偷梁换柱”, 实例化其它View对象或修改view属性view = getLayoutInflater().createView(name, null, attrs);} catch (ClassNotFoundException e) {e.printStackTrace();}long cost = System.currentTimeMillis() - startTime;Log.d(TAG, "加载布局:" + name + "耗时:" + cost);int n = attrs.getAttributeCount();for (int i = 0; i < n; i++) {Log.e(TAG, attrs.getAttributeName(i) + " , " + attrs.getAttributeValue(i));}//hook控件或属性if (view != null && view instanceof Button) {((Button) view).setText("我是hook替换的标题");}return view;     }@Override public View onCreateView(String name, Context context, AttributeSet attrs) {return null;}});setContentView(R.layout.activity_main);}

回调函数里有所有xml布局文件里定义的属性。

按钮的标题变更为“我是HOOK替换的标题”了, 即在Activity的hook函数里可以篡改布局文件里的View属性或实例化其它View对象。

HOOK可以统一管理inflate过程, 具体的应用场景包括:
1、 统计View的inflate时间;
2、归口统一修改View的属性或者实例化其它View对象, 例如全局替换字体。 可以在基类Activity的onCreate函数里替换所有TextView的字体。
3、换肤需求。
4、在hook函数使用new方式实例化自定义View, 但JDK8优化了反射性能, 删除了synchronized同步机制。 参考 https://www.jianshu.com/p/b80ebc5d507c
安卓修改了invoke方法, 直接调用native方法。

   @CallerSensitive// Android-changed: invoke(Object, Object...) implemented natively.@FastNativepublic native Object invoke(Object obj, Object... args)throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;

Android性能优化系列-监听View inflate周期并动态替换相关推荐

  1. Android性能优化系列:启动优化

    文章目录 1 应用启动类型 1.1 冷启动 1.2 温启动 1.3 热启动 2 查看启动耗时 2.1 adb命令查看 2.2 Logcat Displayed查看启动耗时 2.3 手动记录启动耗时 2 ...

  2. Android性能优化系列之内存优化

    在Java中,内存的分配是由程序完成的,而内存的释放是由垃圾收集器(Garbage Collection,GC)完成的,程序员不需要通过调用函数来释放内存,但也随之带来了内存泄漏的可能,上篇博客,我介 ...

  3. Android性能优化系列:CPU收敛优化(线程优化)

    文章目录 线程调度 线程调度的原理 线程调度模型 Android 的线程调度 线程调度小结 Android 异步方式汇总 Thread HandlerThread IntentService Asyn ...

  4. Android性能优化系列之apk瘦身

    Android性能优化系列之布局优化 Android性能优化系列之内存优化 为什么APK要瘦身.APK越大,在下载安装过程中,他们耗费的流量会越多,安装等待时间也会越长:对于产品本身,意味着下载转化率 ...

  5. 抖音 Android 性能优化系列:新一代全能型性能分析工具 Rhea

    本文选自「抖音 Android 性能优化」系列文章. 「抖音 Android 性能优化」系列文章是由抖音 Android 基础技术部门技术专家倾力打造的技术干货内容,和大家分享基础技术团队在打造极致用 ...

  6. Android性能优化系列 + Android官方培训课程中文版

    Android性能优化典范 - 第6季 http://hukai.me/android-performance-patterns-season-6/ Android性能优化典范 - 第5季 http: ...

  7. Android性能优化系列之电量优化

    电量消耗的计算与统计是一件麻烦而且矛盾的事情,记录电量消耗本身也是一个费电量的事情,随着Android开的性能要求越来越高,电量的优化,也显得格外重要,一个耗电的应用,用户肯定会毫不犹豫的进行卸载,所 ...

  8. Android性能优化系列篇(五):弱网优化

    六.弱网优化 1.Serializable原理 通常我们使用Java的序列化与反序列化时,只需要将类实现Serializable接口即可,剩下的事情就交给了jdk.今天我们就来探究一下,Java序列化 ...

  9. 抖音 Android 性能优化系列:Java 内存优化篇

    内存作为计算机程序运行最重要的资源之一,需要运行过程中做到合理的资源分配与回收,不合理的内存占用轻则使得用户应用程序运行卡顿.ANR.黑屏,重则导致用户应用程序发生 OOM(out of memory ...

  10. 你想要的Android性能优化系列:启动优化 !

    文章目录 一.概述 二.应用启动流程介绍 三.优化核心思想 四.时间检测 4.1 Displayed 4.2 adb shell 4.3 reportFullyDrawn() 4.4 代码打点 4.5 ...

最新文章

  1. JDBC连接数据库过程
  2. unittest笔记
  3. python 列表中dict中key排序
  4. 两台服务器数据库怎么自动同步数据库,mysql 多台数据库同步server-id 重复导致的问题...
  5. 计算机 专升硕,2020新西兰专升硕计算机专业可选院校有哪些?新西兰专升硕途径详解!...
  6. python3 logging模块中文乱码_Python logging模块写入中文出现乱码
  7. Excel2013数据透视表、Power View中的钻取
  8. python获取百度迁徙大数据
  9. 【UE4】特效之 Particle System 详解(二)—— 特效池
  10. git 解决授权失败的方法
  11. 黑客攻防之告别脚本小子-----精简实用渗透测试python小白入门
  12. 如何将原来Eclipse的一个工作空间设置好的界面复制到另外一个Eclipse里面
  13. 一个FC游戏的下载站点
  14. Windows下安装pycocotools(本人亲测,可以解决)
  15. 每日记录 8.28 TP(真阳率) NP(假阳率) FP
  16. html下拉菜单读取xml,基于XML的可配置Html下拉框的设计与实现
  17. Cisco Packet Tracer(静态路由配置+默认路由)
  18. 计算机系新年寄语,经典新年寄语(精选50句)
  19. java常量和变量的区别_java常量与变量的区别
  20. 微云网络连锁行业解决方案

热门文章

  1. python数列_Python斐波拉契数列
  2. mxgraph 画布
  3. 域控组策略桌面壁纸设置问题
  4. 二. 再熟悉 Markdown 标准语法
  5. 10个热门大数据发展趋势
  6. SQLServer的top 100 percent用法
  7. 戴尔台式计算机没声音,戴尔电脑没声音怎么回事?四个方法轻松解决
  8. cp: omitting directory”错误的解释和解决办法
  9. 初识机器学习前导内容_你需要知道的基本概念罗列_以PY为工具 【Python机器学习系列(一)】
  10. 2020寒假【gmoj2223】【hen母鸡下蛋】【区间和】