Threading Performance 101. (Android Performance Patterns Season 5, Ep. 1)

接下来呢我会把视频中的英文字幕逐句抄写下来,然后以英文句号分段,中间会穿插着相应的翻译,可能翻译的不准确,毕竟我英文水平也确实不是很好,但英文重要,所以我才通过学习 Android 的同时提升英文阅读水平,所以我尽量不翻译错,如果有错误,请留言指出。

本期视频地址: https://www.youtube.com/watch?v=qk5F6Bxqhr4&t=27s

(3分钟出头的视频老外竟然说了这么多...心好痛)

Ah, threading.

喔,线程。

So powerful that you can fold genomes with it, but so difficult that it can drive the average programmer insane.

fold genomes 折叠基因组是啥意思...我觉得这句大概是就是说线程它确实非常强大,但也并不是那么容易被驾驭的,所以它逼疯了很多程序员(估计是他有很多使用技巧,大家并不知道)。

My name is Cole McCandless, and as far as Android developer is concerned, threading is one of the most important and confusing things that you can deal with, which means if you want to write the fastest app possible, you've gotta take a minute and understand the subtle art that is multithreaded programming.

我叫 Cole McCandless,对于 Android 开发者而言,线程是你将会碰到的最重要和复杂的东西,这意味着如果你想要写出更快的 App,那么你需要花费一些时间去学习多线程编程的微妙的艺术。

Remeber that in the vast world of Android functions there's a whole boatload of operations that only execute on the main thread——system events, input events, application callback services, and even alarms.

请记住在 Android 这个庞大的世界体系中有一些操作只能在主线程去执行他们包括——系统事件,输入事件,应用回调服务以及 Alarm。

And for the most part, any code that you write executes inside one of these operations, which means it also runs on the main thread.

而大多数情况下,你编写的代码都会在上面那些操作中去执行,这就意味着你写的代码也是将运行在主线程的。

主线程.png

Now, if you recall, work that executes on the main thread gets there after being pulled from the front of a work queue, so blocks of work are done in order, and the next blocks of work isn't processed until the current one is completed, whice means if there is a large chunk of work between an input event and its callback, then the user will have to wait longer than expected to see results.

这句话有点难翻译,我认为大概意思是说,如果你还记得,代码是在主线程被执行的,并且有它自己的执行顺序,在它被拉到工作队列的前面,你需要等到它前面的执行完了才能执行下一个任务,这意味着,如果输入事件和它的回调之间有很大的一块代码要执行,那用户将会在超出预期的时间后看到结果。这段主要是说如果把事情都放在主线程去处理会影响事件和回调的处理时间,从而影响用户对 App 的体验,因为他们其实认为我不必等待就可以看到我想要的结果,这才是用户想要的。

你的代码也在主线程.png

And don't forget that the main thread is also where most of the screen rendering occurs.

并且不要忘记主线程也发生大部分屏幕渲染的地方。

While an animation or screen update is occurring, the system will try to draw the screen every 16 milliseconds or so to achieve smooth 60 frames per second.

当动画和界面更新发生的时候,系统将会尝试每 16 ms 绘制屏幕以达到每秒平滑的 60 帧。这里说到了系统会在每 16 ms 去重新绘制屏幕,而如果需要绘制过于复杂的界面就可能会导致卡顿,因为它上去并不平滑,这时候就需要我们去手动优化了。

每隔 16 ms 的 UI 绘制.png

The problem is that this is happening while the thread is also responding to app input events.

问题是主线程除了绘制界面还需要响应 App 的输入事件。

So if your app is in the middle of an animation and some random work packet takes longer than expected, you miss your chance to render that next frame within the 16 millisecond window, and that frame will be delayed.

大概意思是说如果你的 App 在你刷新界面期间你的代码很多要去执行的,那么你可能错过 16 ms 渲染下一帧的机会,它会被延迟到下一次被执行。这也就是为什么会有界面刷新看上去卡顿的原因,因为本来应该这一次被绘制的帧被延迟到了下一次。

延迟绘制.png

This is what we call a dropped frame, and when this happens, users start to notice.

这被称之为掉帧,而用户可以察觉到的它的发生。明显的界面显示不流畅,是被称之为差的用户体验的。

The direct solution here is to move anything that might upset the 16 millisecond window over somewhere else, like to a different thread.

直接的解决方案是移动任何可能导致错过 16 ms 内绘制的代码,比如把可能长时间执行的代码放入到其他线程中去。

放到工作线程去.png

This way it won't be contesting with the UI thread for work to be done, and won't be interrupting the drawing of the screen, which is the whole point threading on Android in a nutshell.

这样(说的是上一句可以另起一个线程)它就不必和UI线程去竞争,不会打断屏幕绘制,which is the whole point threading on Android in a nutshell.这句话好难翻译...毕竟主线程是非常重要的。

So the question at hand, what's the best way to offiload this work, and how do you choose what types of work to offload?

所以手头的问题是什么是最好的处理方式并且如何选择。

Thankfully, the Android framework and provided a handful of classes to help make this a bit easier for you.

感谢的是 Android 提供了一些有帮助的类使得解决问题变得简单。

Android提供.png

For example, the AsyncTask class is ideal for helping you get work on and off the UI thread the right way.

例如 AsyncTask 类是一个理想的可以帮我们正确使用 UI 线程的方法,因为它内部封装了线程池,你只需告诉他你需要在后台做什么,需要返回什么数据,它会自己帮我们处理好这些,耗时的操作被放到了后台线程而返回结果可以在主线程被拿到,但感觉生活中很少会有人用到它。

HandlerThreads are great when you need a dedicated thread for callbacks to land on.

当我们需要一个专用的线程来回调时,HandlerThreads 是很不错的选择。因为对我们来说如果我们在主线程去使用Handler时,主线程自带了一个 Looper,而在其他线程使用Handler时却需要注意自己手动创建一个 Looper,HandlerThread 是 Android 已经帮我们封装好的线程,它已经为我们提供好了一个 Looper,不需要我们手动去调用 Looper.prepare() 和 Looper.loop()。

ThreadPools work best when you break you work up into really small packets, and then toss them to a bunch of threads, and IntentServices are really ideal for background tasks, or when you need to get intent work off the UI thread.

线程池是当我们有很多需要太后处理的任务时不错的选择,因为它自己会我们管理线程,包括线程的创建、销毁和复用等等,IntentServices 是一个很不错的后台服务,服务本身是 Android 四大组件之一,自定义的服务我们需要自己去管理它的生命周期,IntentServices 它会在执行完我们指定任务后调用 stopSelf 去结束自己,它的源码很短所以建议大家去看看,它是通过 HandlerThread 把 onHandleIntent 的任务指定在后台线程去做,在 onStart 时通过 Handler 去通知后台线程执行 onHandleIntent 和 stopSelf,从而自己管理了自己。

And like everything else, there is not a silver bullet here, but knowing which primitive is best for what situation can save you a lot of headaches.

这句话大概意思是说和其他的一样,这里并没有最合适的方法,你需要根据自己的需求判断哪个更适合自己当前使用。

But note that having all those fancy helper classes doesn't hide the big problem, memory.

但请注意拥有这些方便操作类并不会隐藏一个很大问题,内存。

See threading and memory have never really played well, and on the Android platform it's no different.

大概意思是我们看得出线程和内存并没有相处的很好,在 Android 平它是也没有什么不同。

For example, if you declare one of those fancy threading primitives inside
of an activity, it now contains an implicit reference to the outer activity, which can cause a memory leak if the activity is destroyed, but the threaded work is still alive.

例如,我们在 Activity 中声明了一个线程,而这个线程包含了外部Activity的一个隐式的引用,如果 Activity 被销毁但线程还活着那么它可能会导致内存的泄露。

内部类隐私持有外部类引用而导致的内存泄漏,推荐使用嵌套类,带有 static 关键字的内部类.png

Or, what happens when the user rotates the device, destroying an activity that spawned a bunch of threaded work?

大概意思是,当用户旋转屏幕时会发什么什么?会销毁 Activity,而这个 Activity 上面还有这个大量的工作线程(这个我真的没有注意过)。

I mean, chances are that those work packets would have references back to various UI objects that don't really exist anymore.

我的意思是,它们还会引用着那些已经不存在的UI对象。所以弱引用是的不错的选择,如果引用还在就继续使用,如果引用已经被回收就不能继续使用了,当然使用什么引用还是需要根据自己的需求。

And the truth is that the Android platform is flooded with threads.

事实上Android平台上充斥着大量线程。

If you need a reminder of that grab a Systrance capture and check out all the cool stuff that's going on underneath the hood that you never really knew about.

这句话啥意思坑爹呢。。。大概是说利用 Systrance 可以捕捉和检查一些问题。

See, at the end of the day threading is critical to ensure high performance of your Android app, but there's lots of other problems that you have to worry about that as well, which is why you should check out the rest of Android Performance Pantterns videos.

线程对于确保 Android App 的高性能确实至关重要,但也有很多其他的问题需要我们去关心,这也是为什么我们应该看完其他 Android Performance Pantterns 视频的原因(哈哈哈实力推荐自己的视频666666)。

And also, don't forget to jion our Google+ community so that you can ask questions when you run into problem.

别忘了加入他们Google+中的交流,让你遇到问题他们会给出解答。大概是这里https://plus.google.com/u/0/collection/Yztxb

So keep calm, profile your code, and always remember, perf matters.

保持冷静,配置你的代码(?是这么翻译么)。

这是我翻译的第一篇,英语水平还不够好,不过也正是因为不够好才要去做这个,所以你也看到了我在翻译的过程中会加入一些自己的理解,希望对你有帮助。如有翻译不正确的地方请留言。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容