Android-APP启动优化

  • 伪优化
    • 案例
    • 占位图方案
    • 总结(修改全局的主题)
    • 修改局部的主题
  • 真正的优化
    • 优化
    • 真正优化的总结

黑白屏问题优化
黑白屏在商业APP中的价值
如何使用Traceview工具对优化定位处理

伪优化

用于用户体验,用来给到用户体验,没有实质性的优化

案例

注意看这一块(parent=“Theme.AppCompat.Light”)
如果没写这一块,启动时会是一个黑屏,写了这一块,启动时会是一个白屏;

     <style name="AppTheme" parent="Theme.AppCompat.Light">                "colorPrimary">@color/colorPrimary        "colorPrimaryDark">@color/colorPrimarydark        "colorAccent">@color/coloraccent                "windowNoTitle">true        "windowActionBar">false                "android:windowAnimationStyle">@style/activityAnimation    style>

相信很多人,经常在Application中做一些初始化,这样会造成启动时白屏的时间延长,有些好的手机上面可能发现不了,我们这里就做了个延时3秒来模拟下;
注意看下面的GIF图,在冷启动时点击启动app的时候,注意看启动时的白屏;

public class App extends Application { @Override    public void onCreate() {        super.onCreate();        File file = new File(Environment.getExternalStorageDirectory(), "app1.trace");        Log.i(TAG, "onCreate: " + file.getAbsolutePath());        //把分析结果存在一个文件        Debug.startMethodTracing(file.getAbsolutePath());        //对全局属性赋值        mContext = getApplicationContext();        mMainThread = Thread.currentThread();        mMainThreadId = android.os.Process.myTid();        mMainLooper = getMainLooper();        mHandler = new Handler();        try {        //这里来模拟做一些初始化工作            Thread.sleep(3000);        } catch (InterruptedException e) {            e.printStackTrace();        }        NIMClient.init(this, loginInfo(), options());        Debug.stopMethodTracing();    }}

这一块白屏是不是很难看?
注: 这个不是微信,这个是我在码云上面下载的一个模仿微信的项目哦;

以前都会觉得是个很难看的bug,现在很多软件会利用这个白屏时间,显示一张背景图;

占位图方案

我想大家应该知道parent就是父类吧,也是继承的样式吧 ?
我们跟着这个parent="Theme.AppCompat.Light"父类,一层一层的往下找;
最终看到这个(Platform.AppCompat.Light)样式
android:windowBackground:看名字应该知道吧,窗口背景;

 <style name="Platform.AppCompat.Light" parent="android:Theme.Light"> ...... "android:windowBackground">@color/background_material_light ...... style>

我们来修改这个android:windowBackground ,注意不是在这个里面直接修改!!!

我们在自己的主题里面将android:windowBackground 修改为蓝色;下面来看看效果;

     <style name="AppTheme" parent="Theme.AppCompat.Light">     --在这里重写android:windowBackground  将它的颜色改为蓝色-->        "android:windowBackground">@color/assist_blue_down                "colorPrimary">@color/colorPrimary        "colorPrimaryDark">@color/colorPrimarydark        "colorAccent">@color/coloraccent                "windowNoTitle">true        "windowActionBar">false                "android:windowAnimationStyle">@style/activityAnimation    style>

我们修改成蓝色后,注意到没?启动时候,这里使我们自己设置的蓝色了吧?那是不是就可以在这类放一张启动图片了?
这里放一张启动图片(广告图)后,那启动的时候,就先出来的是那张启动图片(广告图)了;

来看看用图片的效果
我们来放这张图片,来看看效果

总结(修改全局的主题)

这样直接修改全局的主题会有个不好的问题,就是会造成APP的每一个页面都会有这样一个背景图,就会牵扯到布局优化的过度渲染了,如果不了解布局优化的,请移步到我的另一篇博客中:
Android UI绘制优化及建议

修改局部的主题

我们这里新加一个主题;将背景设置成广告的图片

       <style name="AppTheme.Launcher1">        "android:windowBackground">@drawable/bg    style>

然后在这个LAUNCHER页面中去设置这个独立的主题Launcher1

 <activity            android:theme="@style/AppTheme.Launcher1"            android:name=".activity.SplashActivity"            android:screenOrientation="portrait"            >            <intent-filter>                <action android:name="android.intent.action.MAIN"/>                <category android:name="android.intent.category.LAUNCHER"/>            intent-filter>        activity>

在代码中再设置主题,效果和上面一样,这里我就不放gif图片了

public class SplashActivity extends BaseActivity {    private static final String TAG = "david";    @Override    protected void onCreate(Bundle savedInstanceState) {//        setTheme(R.style.AppTheme);        super.onCreate(savedInstanceState);        setTheme(R.style.AppTheme_Launcher1);    }}

真正的优化

尽可能的去减少Activity、Application中onCreate中的耗时代码;
我们来分析Application中onCreate方法的耗时
启动时间:Debug.startMethodTracing(file.getAbsolutePath());
结束时间:Debug.stopMethodTracing();
用这两个方法的调用来,记录这个时间,生成.trace文件,注意要开好文件存储权限;
直接冷启动运行APP,生成文件,然后我们把文件导出来

然后把这个文件拖入到我们的AS里面;

结合我们这个Application中的onCreate来看上面的图
可以发现第一行自己调用的方法吧,然后对应段落下出现了很多各种段落,表示的是方法中调用的其方法,第一行可以看得出这个对应方法以及内部调用后的所需要时间,也就是每个方法的执行耗费的时间;
鼠标放到上面,可以有这个方法执行所耗费的时间注意看我鼠标那,框中最下面显示:6.62ms (表示这个方法执行了6.62毫秒)

public class App extends Application {    private static final String TAG = "jett";    public static List<Activity> activities = new LinkedList<Activity>();    @Override    public void onCreate() {        super.onCreate();        File file = new File(Environment.getExternalStorageDirectory(), "app1.trace");        Log.i(TAG, "onCreate: " + file.getAbsolutePath());        //把分析结果存在一个文件        Debug.startMethodTracing(file.getAbsolutePath());        //对全局属性赋值        mContext = getApplicationContext();        mMainThread = Thread.currentThread();        mMainThreadId = android.os.Process.myTid();        mMainLooper = getMainLooper();        mHandler = new Handler();        //因为LQRUIKit中已经对ImageLoader进行过初始化了        initImageLoader(getApplicationContext());        initNim();        initImagePicker();        initOkHttp();        NIMClient.init(this, loginInfo(), options());        Debug.stopMethodTracing();    }    private void initOkHttp() {    }}

如果不喜欢看图的,也可以来看看这个

上图中,第三列%:表示这段总耗时,每个方法对应消耗的百分比;
注意看:initImageLoader、initNim方法耗时占比比较大吧?
我们就需要解决掉这两个方法的耗时,这两个方法处理的价值是最大的,其余的想处理的也可以去处理,看个人;

优化

这类我们将耗时的、对异步要求不高、调用的方法中没去创建handler 没操作UI 的初始化方法,放到了子线程中去调用;
并将可以做懒加载的方法,注释掉,让需要用的地方去做懒加载;

public class App extends Application {    private static final String TAG = "jett";    public static List<Activity> activities = new LinkedList<Activity>();    @Override    public void onCreate() {        super.onCreate();        File file = new File(Environment.getExternalStorageDirectory(), "app1.trace");        Log.i(TAG, "onCreate: " + file.getAbsolutePath());        //把分析结果存在一个文件        Debug.startMethodTracing(file.getAbsolutePath());        //对全局属性赋值        mContext = getApplicationContext();        mMainThread = Thread.currentThread();        mMainThreadId = android.os.Process.myTid();        mMainLooper = getMainLooper();        mHandler = new Handler();        //因为LQRUIKit中已经对ImageLoader进行过初始化了//        new Thread(){            @Override            public void run() {                initImageLoader(getApplicationContext());                //如果要用线程来节约了这些初始化的时间                //1.里面的API不能去创建handler                //2.不能有UI操作                //3.对异步要求不高                initNim();                initImagePicker();                initOkHttp();//可以懒加载            }        }.start();        NIMClient.init(this, loginInfo(), options());        Debug.stopMethodTracing();    }}

来看看这个优化后的时间


是不是减少了很多?这样就会让我们APP在启动的时间,减少耗时启动了;

真正优化的总结

优化方案:
1.开线程 调用的方法中没去创建handler 没操作UI 对异步要求不高;
2.懒加载 用到的时候再初始化,如网络,数据库操作;

注意:如果有些需要马上要用到的一些对象和框架,尽量去做懒加载,防止异步加载的对象和框架还没加载完成,在页面中马上使用,造成空指针或者一些异常
还有一些耗时的,可以不放在Application里面,结合懒加载可以在启动页LAUNCHER中,设置主题背景,然后在启动页中启动定时广告,相信大部分框架和代码在这个广告三秒的时间内能初始化完成了。还可以在这三秒中调用下载下一次启动时的图片广告信息等等

感谢收看到最后的童鞋

更多相关文章

  1. Android(安卓)ThreadPoolExecutor线程池
  2. Android中 AsyncTask和Handler对比(特别有用)
  3. Handler ThreadHandler Looper的总结
  4. android下jni开发总结
  5. Binder驱动之设备初始化
  6. Android应用程序资源——menu菜单资源
  7. 【Android架构师java原理专题详解】一;泛型原理详解
  8. Android常见面试题&字节跳动、阿里、腾讯2019实习生Android岗部
  9. Android(安卓)Phone进程启动过程详解

随机推荐

  1. 【Android 电量优化】JobScheduler 相关
  2. Android设置Selector不同状态下颜色及图
  3. Android Retrofit 2.0(二)使用教程OkHttp3
  4. android Java BASE64编码和解码二:图片的
  5. BroadcastReceiver实现android来去电录音
  6. [置顶] Android(安卓)AsyncTask源码解析
  7. Android(安卓)UI开发详解之Fragment
  8. 通过JNI实现c/c++和Android的java层函数
  9. Android屏幕禁止休眠的方法
  10. android笔记-android基本操作和数据存储