美文网首页Android进阶之路Android开发android开发技巧
APP启动优化,你应该没看到过这样子的

APP启动优化,你应该没看到过这样子的

作者: Sky_Blue | 来源:发表于2020-05-21 10:40 被阅读0次
一、检测APP启动耗时
  1. 用Android系统Debug API 生成文件,记录启动耗时操作。
  2. 用AndroidStudio Profiler 查看耗时操作排行
    生成追踪耗时文件代码如下:
/**
 * 运行时间跟踪
 */
public class TrackUtils {
    private TrackUtils() {
    }

    private static class Holder {
        private static final TrackUtils instance = new TrackUtils();
    }

    public static TrackUtils getInstance() {
        return Holder.instance;
    }

    public void start() {
        // 追踪启动时间
        if (BuildConfig.IS_DEBUG) {
            File file = new File(Environment.getExternalStorageDirectory(), "app.trace");
            Log.e("start", "start: " + file.getAbsolutePath());
            Debug.startMethodTracing(file.getAbsolutePath());
        }
    }

    public void end() {
        // 追踪结束时间
        if (BuildConfig.IS_DEBUG) {
            Debug.stopMethodTracing();
        }
    }
}
  1. 使用方式
TrackUtils.getInstance().start();
// ... 初始化内容
TrackUtils.getInstance().end();
  1. 导出app.trace文件,拖到AdroidStudio查看如图所示


    trace.png
  2. 找到耗时的操作
二、耗时操作处理方式(Kotlin协程处理)
  1. 经过多次实战测试,用线程池也不行,发现用Kotlin的协程处理最优。
  2. Kotlin的协程核心思想还是线程,优点:开启线程后挂起操作,不占用主线程的资源,任务执行完后自动切换到主线程。
  3. 部分三方在线程初始化要注意:Handler消息发送(Looper的操作)。
三、实现代码,要使用Kotlin的代码,不懂Kotlin的自己去了解一下

/**
 * 初始化任务类
 */
public abstract class InitTask  {
    // 要不要开启Looper
    private boolean isLooper;

    public InitTask() {
        this(false);
    }

    public InitTask(boolean isLooper) {
        this.isLooper = isLooper;
    }

    public void run() {
        //设置线程的优先级,不与主线程抢资源
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
        if (isLooper) {
            Looper.prepare();
        }
        execute();
        if (isLooper) {
            Looper.loop();
        }
    }

    public abstract void execute();
}

/**
 * 协程工具类:用于APP启动优化
 */
object GlobalScopeUtils {
    fun launch(task: InitTask) {
        // 主线程开启协程
        GlobalScope.launch(Dispatchers.Main) {
            // 挂起:在IO线程执行任务
            withContext(Dispatchers.IO) {
                task.run()
            }
            // 任务执行完自动切换回到主线程
        }
    }
}
四、使用协程初始化
  1. 找出耗时操作,进行分类处理
  2. 将耗时多的,可以单独放在一个协程里面处理。其它的,根据耗时的时间分组来初始化。
    /**
     * 用协程初始化
     */
    public final void initBackground() {
      
        GlobalScopeUtils.INSTANCE.launch(new InitTask() {
            @Override
            public void execute() {
                // 极光推送
                initPush();
                // x5内核
                initX5();
                // 谷歌分析
                initAnalytics();
            }
        });
        // 这些三方要开启Looper
        GlobalScopeUtils.INSTANCE.launch(new InitTask(true) {
            @Override
            public void execute() {
                // 环信IM
                initIM();
                // 百度地图
                initBaiDuMap();
                // 腾讯Bugly
                initBugly();
            }
        });
        GlobalScopeUtils.INSTANCE.launch(new InitTask() {
            @Override
            public void execute() {
                // 分享、短信
                initMob();
                // ReactNative
                initSoLoader();
            }
        });
    }
五、优化前5-10秒,甚至更长。优化后,启动基本2S以下。

相关文章

网友评论

    本文标题:APP启动优化,你应该没看到过这样子的

    本文链接:https://www.haomeiwen.com/subject/rfgaohtx.html