避免在UI线程中进行耗时任务,这应该是我们开发者的共识。因为在主线程进行耗时任务,会造成UI线程卡顿,带来不好的用户体验。更严重者则会出现ANR。所以我们应该尽量把耗时操作放在后台进行,比如 文件的IO操作,对数据库的SQL操作和,对网络的访问,复杂的计算逻辑。
异步操作一般都涉及一下几个问题: 1. 使用什么来进行异步,即创建什么样的工具 2. 如何创建异步任务,即怎么样发送到该工具中 3. 该工具如何将返回值返回给用户
可以执行异步任务的类总结:demo在gittub上戳我
HandlerThread是frameWork为我们提供的一个具有Looper的子线程,可以使用该线程的handler。该处理方式适用于小型的项目,对并发要求不大的。因为它只维持一个Thread,一次只能运行一个任务。
类中代码:
//将任务提交到队列中 public void post(Runnable command) { getHandler().post(command); } //将任务放在队列首部,赶紧执行。适合于读取时候。 public void postAtFrontOfQueue(Runnable command) { getHandler().postAtFrontOfQueue(command); } //延迟一点时间执行该任务。 public void postDelayed(Runnable command, long delayMillis) { getHandler().postDelayed(command, delayMillis); } //在指定时间开始执行。 public void postAtTime(Runnable command, long delayMillis) { getHandler().postAtTime(command, delayMillis); } //退出该WorkThread. public void quit() { if (Build.VERSION.SDK_INT >= 18) { getWorkThread().quitSafely(); } else { getWorkThread().quit(); } }更多封装移步: TinyTaskManager.java
The IntentService class PRovides a straightforward structure for running an Operation on a single background thread. 使用IntentService执行后台任务,在一般用来初始化字典数据,下载一些文件等。它运行在子线程中,并且以Service形式存在,会提高进程的优先级,不容易被系统清理。
可参考上篇线程池 在Android中使用ThreadPoolExecutor,根据项目对异步任务使用多少来自己创建。可以参考一大神的github lite-async
使用LoaderManager异步加载数据库 官方文档Loaders AsyncTasLoader不进行加载操作的原因及解决方法(太坑了)
A CursorLoader to load data backed by a ContentProvider. 如果使用CursorLoader,就必要使用ContentProvider作为其支持。Alternatively, you can implement your own subclass of Loader or AsyncTaskLoader to load data from some other source.当然,也可以继承Loader或者AsyncTaskLoader来实现自己的异步加载类。查看AsyncTaskLoader源码,发现其底层使用的是AsyncTask。╮(╯▽╰)╭。
the given LoaderManager.LoaderCallbacks implementation is associated with the loader, and will be called when the loader state changes. If at the point of this call the caller is in its started state, and the requested loader already exists and has generated its data, then the system calls onLoadFinished() immediately (during initLoader()), so you must be prepared for this to happen. See onLoadFinished for more discussion of this callback在第二次调用init()时候,要注意他会直接调用onLoadFinished()方法。you should prepared for it。(好难用!!!)
这种方式就很简单,直接new Thread().start(),再使用UI线程的handler对象发回UI线程中。 值得注意的是,Android中大多数类都持有Handler对象,大可不必自己创建Handler对象。比如在Activity中直接使用runOnUiThread(),自定义控件时候使用post()方法等。
详细用法请看:AsyncTask-Sample
实用中比较很少用AsyncTask,串行处理任务,核心线程大于一个时,也只能等待该任务完成再完成下一个,会造成线程资源的浪费,感觉不是很实用。
加强理解图:
RxAndroid使得线程的调度变得很简单,现在还未深入学习,之后学完后再添加进来。
参考: 关于Android中工作者线程的思考 官方文档: Best Practices for Background Jobs Android异步指南
新闻热点
疑难解答