Android 性能典范-线程

xiaoxiao2021-02-28  77

主线程要做的事情

作为Android开发者,线程是最重要又是最容易让人迷惑的东西。如果你要写出流畅的app,你必须理解多线程编程。有相当一部分的Android函数都只能在主线程中执行——系统事件,输入事件,application回调服务,alarm等等。大部分情况下,你在这些操作中所写的代码,也是在主线程执行。

你的代码可能会阻碍输入事件的处理

主线程从队首中取出任务执行,下个任务得等到当前任务完成才能被执行。这意味着,当有很多任务在输入事件和回调之间时,用户就要等超过预期的时间才能看到结果。

丢帧

主线程还是渲染执行的地方。当处于动画或者屏幕刷新时,系统会尝试每16ms渲染屏幕一次,以达到每秒60帧的流畅速度。问题在于,如果主线程为了响应输入事件所执行的任务超过预期时,而你的app又处于动画当中,你就会错过16ms窗口内渲染下一帧的机会。丢帧就发生了。

把任务移到工作线程

最直接的解决方法就是将所有可能扰乱16ms窗口的任务,移到另外的线程。这样它就不会和UI线程竞争,也不会中断屏幕刷新。

如何选择工具类

那我们该选择哪种方式减轻主线程的负担呢?Android Framework已经提供了多种工具类去解决这个问题。

AsyncTask 帮组我们将任务在UI线程和非UI线程之间切换HandlerThread 方便线程处理API回调ThreadPool 运行大量并行任务IntentService 适合后台任务,或者需要在非UI线程处理intent

内存泄漏

不过就和其他东西一样,没有银弹。就算有以上这些工具类,也不能避免另外一个大题:内存。 线程和内存两者很难同时处理好。例如,你在activity里面声明了以上任意一个类,它里面就包含了对外部activity的隐性引用。在activity销毁之后,如果线程还在就会导致内存泄漏。

或者设想一下,用户翻转设备时,销毁了一个产生大量线程的activity,很可能那些线程还拥有旧UI对象的引用。实际上,Android系统充斥着大量线程,你可以用Systrace查看。

转载请注明原文地址: https://www.6miu.com/read-55570.html

最新回复(0)