1. 关于 Service 的一些细节
- Service 的种类:Started Service 和 Bound Service,分别对应于 Context.startService(Intent) 和 Context.bindService;
- 如果一个 Service 在 onStartCommand 执行的过程中被终止,则已提交的 Intent 将得不到机会启动,该 Intent 仍会被视为一个挂起的请求,而非一个已启动的请求(started request);
|
|
Local Binding
|
|
IntentService
- IntentService 的 executor 是 HandlerThread。另外不像 AsyncTask,IntentService 的 executor 是可以有多个实例的。
- 重新启动未完成的请求时,需要在 onHandleIntent 中设置:setIntentRedelivery(true);
|
|
- BroadcastReceiver 可以是应用程序的入口,它可以是应用创建的第一个组件(在 Activity 之前)。但该组件只在 onRecive 方法中保持活动,如果在该组件中执行异步任务,那么有可能在组件声明结束后,该组件所在的进程变为空进程,从而导致运行时在异步任务未完成时杀死该进程,以致丢失任务;
- 为解决此情况,BroadcastReceiver 与 IntentService 的结合是一个理想的解决办法。
2. 关于 Loader
- 特征:当有新的数据(或数据更新)时,自动触发回调;当 Activity 或 Fragment 停止时,自动停止;必要时缓存数据(Activity 配置变更时);避免了与线程相关的内存泄漏(仍有可能会在 Activity 变更配置重新生成时发生内存泄漏);
- 包含:LoaderManager(抽象类), Loader, AsyncTaskLoader, 和 CursorLoader 类
- 生命期:reset -> start <-> stop -> abandon -> reset

LoaderManager
- LoaderManager getLoaderManager();
- Loader
initLoader(int id, Bundle args, LoaderCallbacks callback),如果识别码符合则可重用已有的 Loader - Loader
restartLoader(int id, Bundle args, LoaderCallbacks callback),不可重用,如果已有 Loader,该 Loader 将被销毁(包括数据)并重新创建一个新的; - Loader
getLoader(int id) - void destroyLoader(int id)
事件序列
- Loader 初始化:由 LoaderManager.initLoader 触发;
- 加载数据:客户可使用 Loader.forceLoad() 强制加载新的数据;客户同样可调用 Loader.cancelLoad() 取消加载;
- 重置 Loader

|
|
AsyncTaskLoader
- 加载可以因为内容变更或用户调用 forceLoad() 而触发,因此,频繁的更新或许使得 UI Thread 失去响应能力,这时,可以使用延时加载以解决:setUpdateThrottle(long delayMs)。
CursorLoader(见下面 ContentProvider 一节)
自定义 Loader
- 后台加载(AsyncTaskLoader):public D loadInBackground() { … }
|
|
自定义 File Loader
|
|
3. 关于 BroadcastReceiver 的一些细节
- 从 API Level 11 开始,使用 BroadcastReceiver.goAsync() 方法可以简化执行异步任务,它将在 BroadcastReceiver.PendingResult 中保留异步执行的状态,并且延长 broadcast 的生命期直到 BroadcastReceiver.PendingResult 的状态为 finish。
|
|
4. 关于ContentProvider 的一些细节
- Faster Database Access with Write-Ahead Logging:db.enableWriteAheadLogging(); 【Write-Ahead Logging (WAL) 】
使用 AsyncQueryHandler(抽象类)
- final void startDelete(int token, Object cookie, Uri uri, String selection, String[] selectionArgs)
- final void startInsert(int token, Object cookie, Uri uri, ContentValues initialValues)
- final void startQuery(int token, Object cookie, Uri uri, String[] projection, String selection, String[] selectionArgs, String orderBy)
- final void startUpdate(int token, Object cookie, Uri uri, ContentValues values, String selection, String[] selectionArgs)
|
|

- 示例
|
|
使用 CursorLoader
- 构造器:CursorLoader(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
- 示例
|
|
5. 选择异步技术
