Android多线程性能优化(一)

本文探讨了Android多线程性能优化的重要性,指出直接new Thread()的弊端,强调了管理线程数量和复用的重要性。文章详细分析了UI线程的源码,包括Activity.runOnUiThread()、View.post()和Handler的使用。同时,提到了AsyncTask的执行流程及其优缺点,指出其不可重用和并发限制。最后,预告将介绍更多的多线程优化方案。
摘要由CSDN通过智能技术生成

本文为楼主原创,转载请表明出处:http://blog.csdn.net/Suma_sun/article/details/51584026

在程序开发中,为了让程序表现的更快更流畅,我们会使用多线程来提升应用的并发性能。但多线程并发代码是一个棘手的问题,线程的生命周期处理不好就会造成内存泄漏。

    new Thread(){
        @Override
        public void run() {
            doSomeThing();
        }
    }.start();

上面给出了一个最简单的新建线程并执行任务,也是最不好管理的。为什么?run里面的方法很可能很耗时,直接new出来的线程没有一个对象去接收其句柄,连打断都做不到,只能等待内部错误停止或者任务执行完毕。就算不使用匿名类的方式操作,停止线程光用interrupt()是不够的,该方法只有在线程调用sleep()、join()、wait()交出时间片(阻塞)的时候,它将接收到一个中断异常(InterruptedException),从而提早结束该线程。所以一般都是在run方法里各种操作之前先判断下标志位,是否需要继续执行任务,向外暴露这个标志位的接口,让其变成可控线程。当然普通的thread是满足不了你的,你需要继承thread自行处理标志位的操作,当然如果写成内部类的话最好写成静态内部类,这样避免持有外部类的引用造成泄漏。

经常new Thread().start()的话会加大性能的开销,虽然并发量上去了(不要无止尽的新建线程,处理线程跟cpu核数有关,线程数超出CPU核数过多反而会降低效率,并发得不偿失,因为切换线程是要切换上下文环境的,此操作开销十分大),但是开销变大了。所以管理好线程的个数、复用成为重中之重。

这里写图片描述

你以为这样就结束了?
打出上面那段话我突然想起小时候看的《西游记后传》里的一句经典台词——我还没出力呢,你就趴下了。

Android多线程性能优化前篇-UI线程源码剖析

ps:其实真正的标题在这(>_<:.),其实原本没打算写ui线程的,在整合资料的时候看到了,就顺便写写吧,没想到一写就写那么多…标题都对不上号了,只好修改了

上面说了Thread不足的地方,各位可以思考下有什么解决方案,下篇我再给大家介绍几个方案。

操作UI线程
- Activity.runOnUiThread(Runnable)
- View.post(Runnable) 、 View.postDelay(Runnable , long)
- Handler
- AsyncTask
- IntentService

首先是Handker这个大家天天用应该不用我说了吧,不清楚的可以看我另一篇面试经典题Handler机制回答

 public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else {
            action.run();
        }
    }

上面给出了runOnUiThread的源码,看到关键对象mHandler就知道了,当前线程如果不在主线程(UI线程)就调用activity内的全局handler进行UI操作。PS:在我打开源码之前就想到里里面估计也是有一个Handler来执行UI操作,没想到打开居然中标了,感觉最近还是有些许提升的。哈哈,装完逼,我继续讲~

 public boolean post(Runnable action) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.post(action);
        }
        // Assume that post will succeed later
        ViewRootImpl.getRunQueue().post(action);
        return true;
    }

 public boolean postDelayed(Runnable action, long delayMillis) {
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            return attachInfo.mHandler.postDelayed(action, delayMillis);
        }
        // Assume that post will succeed later
        ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
        return true;
    }

从源码可以看出当attachInfo不为空的时候会调用其内部持有的handler进行UI操作。那AttachInfo是什么鬼呢?

    /**
     * A set of information given to a view when it is attached to its parent
     * window.
     */
    final static class
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值