Android启动优化--异步优化

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();  // 启动器等待
    }

Resource Page Description 在以前的文章中,我曾多次强调应用程序中异步化的重要性。尤其对于IO密集型操作,异步执行对于应用程序的响应能力和伸缩性有非常关键的影响。正确使用异步编程能够使用尽可能少的线程来执行大量的IO密集型操作。可惜的是,即时异步编程有避免线程阻塞等诸多好处,但是这种编程方式至今没有被大量采用。其原因有很多,其中最主要的一点可能就是异步模型在编程较为困难,导致许多开发人员不愿意去做。 异步,则意味着一个任务至少要被拆分为“二段式”的调用方式:一个方法用于发起异步请求,另一个方法用于异步任务完成后的回调。与传统方法调用方式相比,异步调用时的中间数据不能存放在线程栈上,方法之间的也不能简单地通过参数传递的方式来共享数据。此外,传统方法调用中的try…catch…finally,using等关键字都无法跨越方法边界,因此异步编程在处理异常,保护资源等方面也需要花更大的精力才行。如果一不小心,轻则造成资源泄露,重则使整个应用程序崩溃。 因此,无论是微软官方还是社区中都出现了一些简化异步编程方式的组件,例如微软并行与协调运行时和Wintellect's .NET Power Threading Library中的AsyncEnumerator。同时,我基于AsyncEnumerator构建了一个AsyncTaskDispatcher组件,使多个有依赖关系的异步操作之间的协作调用得以大大简化。 以上是引用,自己做了个更简单的demo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值