Android App卡顿慢优化之多线程优化

本博客涉及的内容有:多线程并发的性能问题,介绍了AsyncTask,HandlerThread,IntentService与ThreadPool分别适合的使用场景以及各自的使用注意事项,这是一篇了解Android多线程编程不可多得的基础文章,清楚的了解这些Android系统提供的多线程基础组件之间的差异以及优缺点,才能够在项目实战中做出最恰当的选择。1)Threading Performanc
摘要由CSDN通过智能技术生成

本博客涉及的内容有:多线程并发的性能问题,介绍了AsyncTaskHandlerThreadIntentServiceThreadPool分别适合的使用场景以及各自的使用注意事项,这是一篇了解Android多线程编程不可多得的基础文章,清楚的了解这些Android系统提供的多线程基础组件之间的差异以及优缺点,才能够在项目实战中做出最恰当的选择。

1)Threading Performance(线程性能问题)

在程序开发的实践当中,为了让程序表现得更加流畅,我们肯定会需要使用到多线程来提升程序的并发执行性能。但是编写多线程并发的代码一直以来都是一个相对棘手的问题,所以想要获得更佳的程序性能,我们非常有必要掌握多线程并发编程的基础技能。

众所周知,Android程序的大多数代码操作都必须执行在主线程,例如系统事件(例如设备屏幕发生旋转),输入事件(例如用户点击滑动等),程序回调服务,UI绘制以及闹钟事件等等。那么我们在上述事件或者方法中插入的代码也将执行在主线程。

 

一旦我们在主线程里面添加了操作复杂的代码,这些代码就很可能阻碍主线程去响应点击/滑动事件,阻碍主线程的UI绘制等等。我们知道,为了让屏幕的刷新帧率达到60fps,我们需要确保16ms内完成单次刷新的操作。一旦我们在主线程里面执行的任务过于繁重就可能导致接收到刷新信号的时候因为资源被占用而无法完成这次刷新操作,这样就会产生掉帧的现象,刷新帧率自然也就跟着下降了(一旦刷新帧率降到20fps左右,用户就可以明显感知到卡顿不流畅了)

 

为了避免上面提到的掉帧问题,我们需要使用多线程的技术方案,把那些操作复杂的任务移动到其他线程当中执行,这样就不容易阻塞主线程的操作,也就减小了出现掉帧的可能性。

 

那么问题来了,为主线程减轻负的多线程方案有哪些呢?这些方案分别适合在什么场景下使用?Android系统为我们提供了若干组工具类来帮助解决这个问题。

·AsyncTask: UI线程与工作线程之间进行快速的切换提供一种简单便捷的机制。适用于当下立即需要启动,但是异步执行的生命周期短暂的使用场景。

·HandlerThread: 为某些回调方法或者等待某些任务的执行设置一个专属的线程,并提供线程任务的调度机制。

·ThreadPool: 把任务分解成不同的单元,分发到各个不同的线程上,进行同时并发处理。

·IntentService: 适合于执行由UI触发的后台Service任务,并可以把后台任务执行的情况通过一定的机制反馈给UI

了解这些系统提供的多线程工具类分别适合在什么场景下,可以帮助我们选择合适的解决方案,避免出现不可预期的麻烦。虽然使用多线程可以提高程序的并发量,但是我们需要特别注意因为引入多线程而可能伴随而来的内存问题。举个例子,在Activity内部定义的一个AsyncTask,它属于一个内部类,该类本身和外面的Activity是有引用关系的,如果Activity要销毁的时候,AsyncTask还仍然在运行,这会导致Activity没有办法完全释放,从而引发内存泄漏。所以说,多线程是提升程序性能的有效手段之一,但是使用多线程却需要十分谨慎小心,如果不了解背后的执行机制以及使用的注意事项,很可能引起严重的问题。

2)Understanding Android Threading(理解Android线程

通常来说,一个线程需要经历三个生命阶段:开始,执行,结束。线程会在任务执行完毕之后结束,那么为了确保线程的存活,我们会在执行阶段给线程赋予不同的任务,然后在里面添加退出的条件从而确保任务能够执行完毕后退出。

 

在很多时候,线程不仅仅是线性执行一系列的任务就结束那么简单的,我们会需要增加一个任务队列,让线程不断的从任务队列中获取任务去进行执行,另外我们还可能在线程执行的任务过程中与其他的线程进行协作。如果这些细节都交给我们自己来处理,这将会是件极其繁琐又容易出错的事情。

 

所幸的是,Android系统为我们提供了LooperHandlerMessageQueue来帮助实现上面的线程任务模型:

Looper: 能够确保线程持续存活并且可以不断的从任务队列中获取任务并进行执行。

 

Handler: 能够帮助实现队列任务的管理,不仅仅能够把任务插入到队列的头部,尾部,还可以按照一定的时间延迟来确保任务从队列中能够来得及被取消掉。

 

MessageQueue: 使用IntentMessageRunnable作为任务的载体在不同的线程之间进行传递。

 

把上面三个组件打包到一起进行协作,这就是HandlerThread ,笔者转载了一篇关于HandlerThread 的实现的文章,点击这里可查看详细

 

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值