AsycTask
维护了一个线程池 看源码可发现它有一个最大线程和最小线程数 分别为(128和5) ,但是这是一个不准确的,最大线程数应该取决于你的CPU 首先它会获取你的CPU数量, 如果你的CPU为双核最大线程数应该为 (2*CPU数量+1) ,核心线程是你的CPU数量
当使用的线程数量越多,栈的资源也就越大,对手机的消耗也就越大,同样电量的消耗也会变大,手机发热量大,比如:当用户不断的刷新listview,抓取服务端的图片资源,显示在用户端的时候,开得线程数量也就越大,会出现以上问题。如何进行低资源消耗呢?根本原因就是开出的手机线程数太大,CPU计算能力就增大,可以去控制线程数,用线程池来解决!
一: AncycTack task;
task.execute(parms);
当执行这个方法的时候 调用的是内部自己的线程池
task.executeOnExecutor(exec, params)
当执行这个方法的时候,是自己自定义的线程池
两者有什么重要的区别呢?
内部的线程池的缺陷:
必须在一个线程完成所有的工作之后才去执行下一个线程的操作
API源码如下: 大概知道为什么了吧?同步机制
public synchronized void execute(final Runnable r) {
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
应用在哪里呢?
比如当你下载图片,并显示图的时候 每个listview条目都需要 task.execute(parms)的话
第一个条目完全显示了,第二个条目图片资源才会显示,这种现象我们不希望发生,我们希望整个界面的listview图片资源都在同时下载显示,我们就需要使用
task.executeOnExecutor(exec, params) 不会被同步所限制
但是需要考虑CPU线程池数量的问题了。
bitmap-utils这个框架给我们解决的这类的问题,当是我们程序猿不能只知道怎么去使用框架,还要知道最原始的技术,才能得到提高,有兴趣可以看看x-utils源码,!!!
二:异步任务给我们封装了handler+message 让我们来看看如何封装的:
源码 如下 :
private static class InternalHandler extends Handler {
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult result = (AsyncTaskResult) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
//自动调用异步中的protected void onProgressUpdate(Void... values) {......}
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
封装了一个静态的handler 为什么异步任务,封装的是静态的,而我们写代码的时候没有声明静态的(没有声明静态会导致内存泄漏),而我们却不去声明呢?
声明静态的话,静态的内部类调用外部类的方法字段很麻烦
为什么会导致内存泄漏呢?
当这个应用关闭的时候 handler+message还在不断的发消息,静态的内部类还持有外部类的引用this,这个activity不会立即被销毁,内存中还持有这个对象,就会导致内存泄漏
就会调用
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);//倒是异步任务中onPostExecute方法的调用
}
mStatus = Status.FINISHED;
}
result.mTask.onProgressUpdate(result.mData);的调用
一旦执行一个数据结果的时候就会调用:onProgressUpdate来更新进度
所以你才会看到 进度条的不断更新
只有doInBackground(...)运行在子线程中,耗时操作,其它三个方法运行在主线程中
但是doInBackground(...) 如何完成在子线程中,进行耗时操作的呢?
如下四个方法的执行顺序如下:
先执行准备--->子线程中执行数据,耗时操作--->执行数据的时候显示的进度--->执行完成后
new AsyncTask<Void, Void, Void>(){
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
};
这个doInBackground方法什么时候,如何调用的:
四个方法的调用一定要结合handler+message
doInBackground:被调用的位置 ,方法
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
return postResult(doInBackground(mParams));
}
};
WorkerRunnable 继承了 Runnable
所以是在子线程中被调用了、
小知识点: 主线程可以进行耗时操作和子线程可以GUI么?
可以,但是一般没人去这么做
比如:
tv=(Textview)findViewById(R,id,tv);
new Thread(new Runnable(){
public void run{
tv.settext("跟新GUI");
}
}).start();
希望这些内容会对读者有帮助!!!!