作者Jotarun (after 60)
看板Android
标题[开发] 小心,AsyncTask 不是万能的
时间Tue Sep 14 12:23:54 2010
[原文] ysl 的程式天堂
http://ysl-paradise.blogspot.com/2010/09/asynctask.html
Don't only use AsyncTask for your download task
要进入 Android 应用开发之门,真的一点都不难,不就是 Java 嘛。这是我最常听到,
刚跨过入门槛开发者告诉我的一句话。
这句话其实是没有错的,Android 应用开发的入门槛,比起其他平台,已经低了许多。要
跨过这门槛,的确是轻松容易许多。不过,如果要从入门到进阶,迈向下一个关卡,你第
一个要了解的是 Activity 的生命周期 和 Process 的生命周期,而且是要『透 . 彻 .
了 . 解』。这一步很重要,却被许多开发者轻忽了。
尤其这 Activity 的生命周期,实际上的行为会比你从文件上看到的说明还来的复杂。也
因此,我发现有不少,即使已有多个 Android 应用开发经验的开发者,在开发 Android
应用时,还是栽了不少跟斗。这第一个问题,就出在这些开发者,还是没达到我说的『透
彻了解』境界。因此,今年的进阶应用开发课程,特地将这一部分加入进来,希望对想踏
入进阶之门的开发者,有所助益。
好了,如果你已经有一段 Android 应用的开发经验,那应该知道在
Main-thread(UI-thread) 中,你不能执行一件需时 5 秒以上的工作,例如网路或资料
库的存取、音乐的播放等等。要不然你的应用就会产生 ANR 错误。要解决这个 ANR 错误
,唯一的方法就是自行建立一个新的 Thread 物件,并将该费时的工作放在
Thread.run() 中执行。关於如何解决 ANR 的细节,我建议你先读 Painless threading
,这是一篇值得一读的好文章。
Painless threading
http://android-developers.blogspot.com/2009/05/painless-threading.html
在这篇文章中,介绍了从 Android 1.5 才加入的 AsyncTask。AsyncTask 很好用,同时
我也建议你研究他的 原始码。AsyncTask 就是太好用了,有些开发者就认为,单用
AsyncTask 就能解决他的问题。其实,我早在请将要执行很久的程式码,放在 Service
中执行这篇中,就已提过。单将费时的程式码放在 Thread.run() 中执行,还是不够的,
请将要执行很久的程式码,放在 Service 中执行
http://ysl-paradise.blogspot.com/2009/01/service.html
你只解决一半的问题。不过,多数开发者不是便宜行事,就是不相信我说的。这些便宜行
事的开发者,就是在赌这系统强制杀掉你应用的机率有多少;而那些不相信我说的,就是
因为他没有透彻了解 Activity/Process 的生命周期。
完整解决费时工作的方法,不仅要将费时的工作放在 Thread.run() 中执行,还要将这个
Thread 放在 Service 中执行。
你要知道 Android 的四大元件,Activity, BroadcastReceiver, Servcice and
ContentProvider,除了 ContentProvide 外,全都是在 main-thread 中执行。而这些元
件中,就只有 Service 的生命周期是最持续(长久)的。Activity 只要执行到 onPause()
,BroadcastReceiver 只要离开 onReceiver(),系统随时会杀掉这些元件,而且机率还
很高。Service 当然也是会被系统砍掉,只不过它的优先顺序,排在较低等级。自然被系
统砍掉的机率就低很多。你还可以更进一步利用 Serivce.startForeground() 降低你被
系统杀掉的优先顺序。关於这部分,你要熟读 Process 的生命周期 与 What is a
Service?。
其实为了减轻开发者的负担, Android 1.5 已经加了 IntentService 这个新类别。如果
你要写个用到网路的应用,用这个 IntentService 才是你的完美解决方案。
要使用这个 IntentService 其实很简单,你只要继承这个 IntentService 并将该项费时
的工作,移到 onHandleIntent() 中即可。onHandleIntent() 是被 non-UI thread 所唤
起的。因此在这里面你可以放心地去执行你的下载工作。
下次,我们来研究一下这个 IntentService 的原始码,看他是如何做的。
--
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.113.148.73
1F:推 cjoe:不要拖稿!!! 我要看IntentService怎麽运作 09/14 12:33
2F:→ cjoe:感谢大大的分享 09/14 12:33
3F:→ Jotarun:去跟ysl前辈催稿阿 XD 09/14 12:38
4F:→ meya:谢谢大大分享 09/14 12:48
5F:推 terrybob:推好文! 09/14 12:52
6F:推 ericinttu:推好文 敲碗别拖稿XD 09/14 13:01
7F:推 abccbaandy:推专业 09/14 13:18
8F:推 wyvernlee:千万别富坚哪!! 09/14 14:15
9F:推 jazzhuang:推 09/14 15:30
10F:推 chris:纯推不下!眼花花!! 09/14 19:03
11F:推 BGrap:赞 09/14 19:29
12F:→ coronach:好文......没推了 囧 09/14 19:55
13F:推 TKforce:推! 09/14 20:37
14F:推 jc1989824:好文m 09/15 19:51
15F:推 madoka82:好文...给推...虽然我还没正式跳下去写 Java >口< 09/16 23:58
16F:推 milochen:好文 推 09/22 12:41