首页 > 试题广场 >

android中如何处理耗时操作, asyncTask有什么

[问答题]
android中如何处理耗时操作, asyncTask有什么不足之处
推荐
之前花时间研究过这个问题,这里简单回答一下。

Android处理耗时的操作基本思路为将耗时的操作放到非UI线程执行。常用的是AsyncTask,Handler和Thread,Loaders. 

关于放在非UI线程处理的思路大概有这样几种,一种是每次耗时操作启动一个线程,代价比较大,另一种是将所有的一部放入队列,有一个或者几个线程去执行,比如HandlerThread和AsyncTask.

AsyncTask使用起来比较轻量,但是其自身也存在一些问题。主要表现在

1.cancel方法实现不是很好.
如果你调用了AsyncTask的cancel(false),doInBackground()仍然会执行到方法结束,只是不会去调用onPostExecute()方法。但是实际上这是让应用程序执行了没有意义的操作。那么是不是我们调用cancel(true)前面的问题就能解决呢?并非如此。如果mayInterruptIfRunning设置为true,会使任务尽早结束,但是如果的doInBackground()有不可打断的方***失效,比如这个BitmapFactory.decodeStream() IO操作。但是你可以提前关闭IO流并捕获这样操作抛出的异常。但是这样会使得cancel()方法没有任何意义

2.内存泄露问题
还有一种常见的情况就是,在Activity中使用非静态匿名内部AsyncTask类,由于Java内部类的特点,AsyncTask内部类会持有外部类的隐式引用。由于AsyncTask的生命周期可能比Activity的长,当Activity进行销毁AsyncTask还在执行时,由于AsyncTask持有Activity的引用,导致Activity对象无法回收,进而产生内存泄露。

3.结果丢失

另一个问题就是在屏幕旋转等造成Activity重新创建时AsyncTask数据丢失的问题。当Activity销毁并创新创建后,还在运行的AsyncTask会持有一个Activity的非法引用即之前的Activity实例。导致onPostExecute()没有任何作用。


4.串行并行多版本不一致
1.6之前为串行,1.6到2.3为并行,3.0之后又改回为串行,但是可以通过executeOnExecutor(Executor)实现并行处理任务。

我之前关于AsyncTask的研究文章 http://droidyue.com/blog/2014/11/08/bad-smell-of-asynctask-in-android/

编辑于 2015-01-07 20:22:15 回复(1)
耗时操作处理:放到异步线程中进行操作。
Asynctask的不足之处:
1.AsyncTask可能存在新开大量线程消耗系统资源和导致应用FC的风险
2.AsyncTask一旦执行了 doInBackground,就算调用取消方法,也会将 doInBackground里面的代码执行完毕,才会停止。
3.线程池不经维护,当大量异步发生时,导致线程池满了,会出异常。
发表于 2014-12-31 10:54:29 回复(0)
android中的耗时操作在子线程中执行,数据简单、单个后台异步处理使用AsyncTask:实现代码简单;数据量多且复杂、多后台任务使用handler+thread 。相比较 AsyncTask来说能更好的利用系统资源且高效,但是多个异步操作和ui并更则会比较复杂
发表于 2015-07-11 00:01:48 回复(0)
1.默认情况下,所有的Service都是在UI线程中执行,如果执行耗时操作,可以重新启动一个线程处理
2.AsyncTask是线程+handler的实现,提前已经实现好了供用户使用。
发表于 2015-04-23 16:03:02 回复(0)
通过线程吧。handler和asyncTask两种方法。
发表于 2015-03-13 22:21:44 回复(0)
1.通常在Android系统中,耗时操作一般放在UI主线程以外进行,原因是因为在Android的有一种响应机制,如果在UI主线程中操作时间超过5秒,就会引起ANR异常,导致应用程序崩溃。
AsyncTask可能存在新开大量线程消耗系统资源和导致应用FC的风险
发表于 2015-02-21 08:46:56 回复(0)
ddd头像 ddd
线程池有限,太多异步会满线程池,导致ANR
会开大量线程消耗系统资源导致应用FC,
一旦doingbackground,cancel不了了

发表于 2015-01-11 19:02:23 回复(0)
线程池队列超过128,会报异常
发表于 2015-01-05 08:10:50 回复(0)
android系统推荐是用asyncTask来处理异步,它包括了准备运行:onPreExecute(),正在后台运行:doInBackground(Params...),进度更新:onProgressUpdate(Progress...),完成后台任务:onPostExecute(Result) 取消任务:onCancelled (),

AsyncTask的构造函数有三个模板参数:

1.Params,传递给后台任务的参数类型。

2.Progress,后台计算执行过程中,进步单位(progress units)的类型。(就是后台程序已经执行了百分之几了。)

3.Result, 后台执行返回的结果的类型。

AsyncTask并不总是需要使用上面的全部3种类型。标识不使用的类型很简单,只需要使用Void类型即可。

不足之处:
1,线程池有限,太多内容同时异步会超时,甚至出现ARN效果。
2,AsyncTask可能存在新开大量线程消耗系统资源和导致应用FC的风险
发表于 2014-12-29 22:53:21 回复(0)