Theme 切换
给用户的感觉是启动变快了,实际上app启动时间没有改变。theme切换就是app刚打开的时候的闪屏页。就是APP冷启动的时候的空白window。
具体做法有三步,如下:
启动优化--异步优化
核心思想:子线程分担主线程任务,并行减少时间。(手机CPU大多是多核的,一个线程只占用一个核心,这样CPU的资源没有利用)
异步优化,分为 : 常规异步优化 和 最优异步优化 两种
常规异步优化
经验:
(1)采用线程池的方法,线程的个数按照CPU的个数来;
(2)并不是每个Application.onCreate()中的语句都需要放在线程池中。比如有的方法里含有“Handler handler = new Handler();”语句,这样的语句在子线程中是不能执行的,因为没有对应的MessageQueue,解决办法是添加Looper,比如“ Handler handler = new Handler(Looper.getMainLooper()); ”
(3)还有一种情况,就是方法必须在Application.onCreate()语句执行完之前,这种也不能丢在线程池中。解决办法是用“ CountDownLatch ”。步骤如下:
(a)定义: private CountDownLatch mCountDownLatch = new CountDownLatch(1);
(b)条件被满足之后的地方使用:mCountDownLatch.countDown();
(c)需要等待条件执行完的地方:mCountDownLatch.await();
// 主要代码:
//线程池
public void threadPool(){
ExecutorService service =Executors.newFixedThreadPool(CORE_POOL_SIZE);
service.submit(new Runnable() {
@Override
public void run() {
FirstTask.onStart();
}
});
service.submit(new Runnable() {
@Override
public void run() {
SecondTask.onStart();
// 这个先执行,才执行await()之后的方法。
mCountDownLatch.countDown();
}
});
service.submit(new Runnable() {
@Override
public void run() {
ThirdTask.onStart();
}
});
// 等待
try {
mCountDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
痛点:
(1)代码不优化
(2)场景不好处理(子任务中有依赖关系)
(3)维护成本高
最优异步优化--启动器
核心思想:充分利用CPU多核,自动梳理任务顺序
启动器流程:
(1)代码Task化,启动逻辑抽象为Task
(2)根据所有任务依赖关系排序生成一个有向无环图
(3)多线程按照排序后的优先级依次执行
实操:
第一步,继承 Task 类,添加需要执行的任务
// (1)需要执行的任务放在,继承Task的类中,的run()方法中。
// (2)也可以继承 MainTask 类,表示执行的是在主线程中
public class InitSecondTask extends Task {
//表示:这个任务需要等待它执行完
@Override
public boolean needWait() {
return true;
}
@Override
public void run() {
//真正我们自己的任务
SecondTask.onStart();
}
}
/**
* 需要在IntiSleepTask之后执行
*/
public class InitThirdTask extends Task {
// 一个任务依赖另一个任务
@Override
public List<Class<? extends Task>> dependsOn() {
List<Class<? extends Task>> task = new ArrayList<>();
task.add(InitSleepTask.class);
return task;
}
@Override
public void run() {
ThirdTask.onStart();
}
}
第二部,启动启动器。
// 将下面的代码放在 Application.onCrate() 的方法体中。
// 启动器方法启动
public void launcherInit(){
// 启动器
TaskDispatcher.init(MyApplication.this);
TaskDispatcher dispatcher = TaskDispatcher.createInstance();
dispatcher.addTask(new InitFirstTask())
.addTask(new InitSecondTask())
.addTask(new InitThirdTask())
.addTask(new InitSleepTask())
.start();
dispatcher.await(); // 启动器等待
}