前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >启动优化三问—字节跳动真题

启动优化三问—字节跳动真题

作者头像
码上积木
发布2020-10-29 16:40:44
7550
发布2020-10-29 16:40:44
举报
文章被收录于专栏:码上积木

之前大家应该看过我写的启动流程分析了吧,那篇文章里我说过分析源码的目的一直都不是为了学知识而学,而是理解了这些基础,我们才能更好的解决问题。所以今天就来看看通过分析app启动流程,我们该怎么具体进行启动优化。

  • App启动流程中我们能进行优化的地方有哪些?
  • 具体有哪些优化方法?
  • 分析启动耗时的方法

App启动流程中我们能进行优化的地方有哪些?

  • Application的attach方法,MultiDexApplication会在方法里面会去执行MultiDex逻辑。
  • Application的onCreate方法,大量三方库的初始化都在这里进行,
  • Activity的onCreate、onStart、onResume方法。

具体有哪些优化方法?

  • 障眼法之闪屏页

为了消除启动时的白屏/黑屏,可以通过设置android:windowBackground,让人感觉一点击icon就启动完毕了的感觉。

代码语言:javascript
复制
        <activity android:name=".ui.activity.启动activity"
            android:theme="@style/MyAppTheme"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <style name="MyAppTheme" parent="Theme.AppCompat.NoActionBar">
      <item name="android:windowBackground">@drawable/logo</item>
  </style>

  • 预创建Activity

对象第一次创建的时候,java虚拟机首先检查类对应的Class 对象是否已经加载。如果没有加载,jvm会根据类名查找.class文件,将其Class对象载入。同一个类第二次new的时候就不需要加载类对象,而是直接实例化,创建时间就缩短了。

  • 第三方库懒加载

很多第三方开源库都说在Application中进行初始化,所以可以把一些不是需要启动就初始化的三方库的初始化放到后面,按需初始化,这样就能让Application变得更轻。

  • WebView启动优化

webview第一次启动会非常耗时,具体优化方法可以看我之前的文章,关于webview的优化。

  • 线程优化

线程是程序运行的基本单位,线程的频繁创建是耗性能的,所以大家应该都会用线程池。单个cpu情况下,即使是开多个线程,同时也只有一个线程可以工作,所以线程池的大小要根据cpu个数来确定。

  • MultiDex 优化

由于65536方法限制,所以一般class文件要生成多个dex文件,Android5.0以下,ClassLoader加载类的时候只会从class.dex(主dex)里加载,所以要执行MultiDex.install(context)方法才能正常读取dex类。

而这个install方法就是耗时大户,会解压apk,遍历dex文件,压缩dex、将dex文件通过反射转换成DexFile对象、反射替换数组。

这里需要的方案就是今日头条方案:

1、在Application的attachBaseContext方法里,启动另一个进程的LoadDexActivity去异步执行MultiDex逻辑,显示Loading。

2、然后主进程Application进入while循环,不断检测MultiDex操作是否完成 3、MultiDex执行完之后主进程Application继续走,ContentProvider初始化和Application onCreate方法,也就是执行主进程正常的逻辑。

所以重点就是单开进程去执行MultiDex逻辑,这样就不影响APP的启动了。

分析启动耗时的方法

  • Systrace + 函数插桩

也就是通过在方法的入口和出口加入统计代码,从而统计方法耗时

代码语言:javascript
复制
class Trace{
    public static void i(String tag){
        android.os.Trace.beginSection(tag);
    }

    public static void o(){
        android.os.Trace.endSection();
    }
}


void test(){
    Trace.i("test");
    System.out.println("doSomething");
    Trace.o();
}

* BlockCanary

BlockCanary 可以监听主线程耗时的方法,就是在主线程消息循环打出日志的地入手, 当一个消息操作时间超过阀值后, 记录系统各种资源的状态, 并展示出来。所以我们将阈值设置低一点,这样的话如果一个方法执行时间超过200毫秒,获取堆栈信息。

而记录时间的方法我们之前也说过,就是通过looper()方法中循环去从MessageQueue中去取msg的时候,在dispatchMessage方法前后会有logging日志打印,所以只需要自定义一个Printer,重写println(String x)方法即可实现耗时统计了。

参考文章

https://juejin.im/post/6844903958113157128


Android开发者们,快来关注公| 众 |号【码上积木】,每天三问面试题,并详细剖析,助你成为offer收割机。 相信积累的力量。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码上积木 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • App启动流程中我们能进行优化的地方有哪些?
  • 具体有哪些优化方法?
  • 分析启动耗时的方法
  • 参考文章
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档