1).Android 价值千万 java线程专题:Wait¬ify&join&Yield
http://blog.csdn.net/whb20081815/article/details/65627387
2).Android 价值千万 java多线程同步 <二>Callable和Future&FutureTask
http://blog.csdn.net/whb20081815/article/details/65630694
3).Android 价值千万 java多线程<三>生产者消费者模型四种实现方法
http://blog.csdn.net/whb20081815/article/details/65635647
4).Android 价值千万 java多线程同步 <四> synchronized&Lock&Atomic6种方式
http://blog.csdn.net/whb20081815/article/details/66971983
5).Android 价值千万java多线程同步 <五>CountDownLatch(计数器)和Semaphore(信号量)
http://blog.csdn.net/whb20081815/article/details/68498371
6).Android AsyncTask 那些你不知道的事
https://blog.csdn.net/WHB20081815/article/details/70332209
7).Android 厉害了ThreadLocal的工作原理和实例分析
https://blog.csdn.net/WHB20081815/article/details/66974651
8).Android Handle消息机制:秒懂Looper、Handler、Message三者关系
https://blog.csdn.net/WHB20081815/article/details/67639060
9).Android 性能优化<八> 多线程优化和线程管理
https://blog.csdn.net/WHB20081815/article/details/77775444
AsyncTask中的几个方法才能完成对任务的定制。经常需要去重写的方法有以下四个:
1. onPreExecute()
这个方法会在后台任务开始执行之间调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框等。
2. doInBackground(Params...)
这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任务。任务一旦完成就可以通过return语句来将任务的执行结果进行返回,如果AsyncTask的第三个泛型参数指定的是Void,就可以不返回任务执行结果。注意,在这个方法中是不可以进行UI操作的,如果需要更新UI元素,比如说反馈当前任务的执行进度,可以调用publishProgress(Progress...)方法来完成。
3. onProgressUpdate(Progress...)
当在后台任务中调用了publishProgress(Progress...)方法后,这个方法就很快会被调用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对UI进行操作,利用参数中的数值就可以对界面元素进行相应的更新。
4. onPostExecute(Result)
当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些UI操作,比如说提醒任务执行的结果,以及关闭掉进度条对话框等。
execute = new AsyncTask<Void, Void, List<CacheContactForUI>>() {
@Override
protected void onPreExecute() {
isFinish.set(true);
loadingView.setVisibility(View.VISIBLE);
super.onPreExecute();
}
@Override
protected void onPostExecute(List<CacheContactForUI> result) {
CXLog.d(TAG, "result-size:" + result.size());
CacheContactItem contactItem = null;
for (CacheContactForUI foUiList : result) {
contactItem = foUiList.contactItem;
if(contactItem!=null){
ArrayList<ContactsAttrItem> phoneNumberMap = contactItem.getPhoneNumberMap();
ArrayList<ContactsAttrItem> templistPhoneNumber = new ArrayList<ContactsAttrItem>();
templistPhoneNumber.clear();
for (ContactsAttrItem itemNumber : phoneNumberMap) {
boolean added = true;
for (ContactsAttrItem temp : templistPhoneNumber) {
if (itemNumber.getData().equals(temp.getData())) {
templistPhoneNumber.remove(itemNumber);
added = false;
} else {
}
}
if (added) {
templistPhoneNumber.add(itemNumber);
CXLog.e(TAG, "add");
}
}
CXLog.e(TAG, "addAll" );
phoneNumberMap.addAll(templistPhoneNumber);
contactItem.setPhoneNumberMap(templistPhoneNumber);
foUiList.setContactItem(contactItem);
}
}
mAdapter.setContactForUIsList(result);
mergeContactsList.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
loadingView.setVisibility(View.GONE);
isFinish.set(false);
}
@Override
protected List<CacheContactForUI> doInBackground(Void... params) {
//isFinish.set(true);
//loadingView.setVisibility(View.VISIBLE);
return initData(itemId);
}
;
}.execute();
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
Result result = doInBackground(mParams);
Binder.flushPendingCommands();
return postResult(result);
}
};
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occurred while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
3.0以前
- private static final int CORE_POOL_SIZE = 5;
- private static final int MAXIMUM_POOL_SIZE = 128;
- private static final int KEEP_ALIVE = 10;
- ……
- private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,
- MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);
3.0以后
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
// We want at least 2 threads and at most 4 threads in the core pool,
// preferring to have 1 less than the CPU count to avoid saturating
// the CPU with background work
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE_SECONDS = 30;
源码分析:
用到很多线程的知识:Executor,FutureTask,AtomicBoolean,ThreadPoolExecutor,BlockingQueue
总结:并行还是串行
在Android 1.6之前的版本,AsyncTask是串行的,在1.6至2.3的版本,改成了并行的。在2.3之后的版本又做了修改,可以支持并行和串行,当想要串行执行时,直接执行execute()方法,如果需要并行执行,则要执行executeOnExecutor(Executor)。
记得以前有个面试题经常会问道:AsyncTask运行的原理是什么?有什么缺陷?
以前对于缺陷的答案可能是:AsyncTask在并发执行多个任务时发生异常。其实还是存在的,在3.0以前的系统中还是会以支持多线程并发的方式执行,支持并发数也是我们上面所计算的128,阻塞队列可以存放10个;也就是同时执行138个任务是没有问题的;而超过138会马上出现
如果我们想要并行执行任务,可以调用AsyncTask的executeOnExecutor方法。如下:
new AsyncTask<Void,Void,Void>(){
@Override
protected Void doInBackground(Void... params) {
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,null);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
其实很好理解的。直接执行executeOnExecutor方法,传入AsyncTask.THREAD_POOL_EXECUTOR线程池。这样就绕过了SerialExecutor任务排队的过程。
AsyncTask内存泄漏问题;非静态内部类持有外部类的引用
AsyncTask可能存在新开大量线程消耗系统资源和导致应用FC的风险,因此,我们需要根据自己的需求自定义不同的线程池,由于篇幅问题,将留到下篇再讲。
- AsyncTask不是被设计为处理耗时操作的,耗时上限为几秒钟,如果要做长耗时操作,强烈建议你使用Executor,ThreadPoolExecutor以及FutureTask
AsyncTask原理:
AnsycTask执行任务时,内部会创建一个进程作用域的线程池来管理要运行的任务,
也就就是说当你调用了AsyncTask.execute()后,AsyncTask会把任务交给线程池,
由线程池来管理创建Thread和运行Therad。最后和UI打交道就交给Handler去处理了。
问题:
“你在项目中,会用什么方案来替换AsyncTask呢?
http://blog.csdn.net/guolin_blog/article/details/11711405
http://blog.csdn.net/lmj623565791/article/details/38614699