AsyncTask与IntentService

馋奶兔 提交于 2019-12-19 16:58:57

https://blog.csdn.net/qq_35572068/article/details/84961265
https://blog.csdn.net/lxg1234567890/article/details/27048949

Android主线程,也就是UI线程,其最大用途在于运行四大组件以及处理他们和用户的交互。其他耗时操作交给子线程,如网络请求、I/O操作,从Android3.0开始,网络访问必须在子线程中进行,否则将会失败并抛弃异常,避免ANR现象。

AsyncTask是轻量级异步任务类,封装了Thread和Handler。

AsyncTask

onPreExecute(),异步执行之前,此方法被调用做一些准备工作。doInBackground()在线程池中执行,此方法用于执行异步任务。doInBackground()在线程池中执行,此方法用于执行异步任务,执行过程中可以调用publishProgress()方法更新任务执行进度。onProgressUpdate()方法在主线程中执行,每次任务进度更新时被调用。onPostExecute()在任务执行完成时被调用,其参数为doInBackground()的返回参数。

执行顺序与联系如下图

代码Demo:

 
public class DownloadFileAsyncTackDemo extends AsyncTask<URL, Integer, Long> {
 
    protected  Long doInBackground(URL... urls){
        int count = urls.length;
        long totalSize = 0;
        for(int i = 0; i < count; i++){
            totalSize += Downloader.downloadFile(urls[i]);
            publishProgress((int) (i / (float) count) * 100 );
            if(isCancelled()){
                break;
            }
        }
        return totalSize;
    }
 
    protected void onProgressUpdate(Integer... progress){
        setProgressPercent(progress[0]);
    }
 
    protected void onPostExecute(Long result){
        Log.d("",String.valueOf(result));
    }
 
}

AsyncTask注意事项:

  1. 必须在主线程中加载,意味着第一次访问AsyncTask必须发生在主线程。
  2. Execute方法必须在UI线程调用。不能直接调用onPreExecute()、doInBackground()、publishProgress()、onPostExecute()、onProgressUpdate()方法。
  3. 一个AsyncTask对象只能被执行一次,既只调用一次。
  4. AsyncTask在4.1.1上是串行的,在2.3.3上是并行的。在3.0版本后可使用executeOnExecutor()方法启动以实现并行。

IntentService:

         IntentService是一种特殊的Service继承自Service,任务执行后会自动停止。因为其是Service,因此优先级会比单纯的线程高。且不容易被系统杀死。第一次启动调用onCreate,每次启动调用一次onStartCommand,在onStartCommd处理每个后台任务的Intent。

OnHandleIntent():抽象类,每次都需要实现。是处理任务的地方

每执行一个后台任务,必须启动一次Intentservice。当有多个后台任务,按照外界发起的顺序执行。

示例:

public class MyService extends IntentService {

    private static final String TAG = MyService.class.getSimpleName();

    private int count = 0;

    public MyService() {
        super(TAG);
        // TODO Auto-generated constructor stub
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // TODO Auto-generated method stub
        //在这里添加我们要执行的代码,Intent中可以保存我们所需的数据,
        //每一次通过Intent发送的命令将被顺序执行
        count ++;
        Log.w(TAG, "count::" + count);
    }
}

在外部组件中开启服务:在这里我们在Activity中利用Intent循环10次开启服务。

for (int i = 0; i < 10; i++) {
        Intent intent = new Intent(MainActivity.this, MyService.class);
        startService(intent);
}

结果:
在这里插入图片描述



IntentService和AsyncTask有啥不同?

总结出一句话:IntentService 是Serivce+handler的结合产物 AsyncTask是thread+handler的结合产物。

为什么用service而不用thread:

1.我们先拿 Thread 来说 ,Thread 的运行是独立于 Activity 的,也就是说当一个 Activity 被 finish 之后 ,如果你没有主动停止 Thread 或者 Thread 里的 run 方法没有执行完毕的话,Thread 也会一直执行。因此这里会出现一个问题:当 Activity 被 finish 之后,你不再持有该 Thread 的引用。另一方面,你没有办法在不同的 Activity 中对同一 Thread 进行控制。

2.1 location serivce 不是一个单独的进程,它和应用程序在同一个进程中。只能在当前应用中调用service。kill当前应用则service也随之消亡。

2.2 remote service 独立与应用程序之外进程的进程(必须在声明的时候以android:process=":remote"方式声明),配合AIDL可以实现进程间的相互调用。remote service所依附的那个应用如果应用kill掉,但是remoteservice还在运行,除非你卸载当前应用。

IntentService 是Serivce+handler的结合产物,可以在onHandleIntent直接处理耗时操作。而本地service和远程service不能在onStart方法中执行耗时操作,只能放在子线程中进行处理,当有新的intent请求过来都会线onStartCommond将其入队列,当第一个耗时操作结束后,就会处理下一个耗时操作(此时调用onHandleIntent),都执行完了自动执行onDestory销毁IntengService服务。

AsyncTask是thread+handler的结合产物,减少程序中线程过多开销过大,操作和管理更加方便。AsyncTask实例必须在UI Thread中创建,execute方法必须在UI Thread中调用不能手动调用onPreExcute(),onPostExcute(Result)。task只能被执行一次,否则将出现异常。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!