IntentService类 和 异步任务(AsyncTask)

IntentService是一个Service类。
IntentService只有1个带String参数的构造方法,所以,在自定义类继承IntentService时,需要在自定义类中显式的调用IntentService带参数的构造方法,并且将自定义类的构造方法修改为无参数的。
IntentService内部使用消息机制,利用消息队列的特性,可以依次处理多个耗时操作。
IntentService具有生命力强、一次性使用、依次处理多个耗时操作的特性。
注意:在自定义类继承IntentService时,可以重写IntentService的生命周期方法,但是,不可以删除super语句

IntentService与ResultReceiver
----------------------------------
ResultReceiver可以实现组件间的通信
【开发流程】
1. 自定义类继承IntentService,显式的定义无参数的构造方法,并注册
2. 在接收结果的类(例如Activity类)中自定义内部类继承ResultReceiver
3. 在需要IntentService执行任务时,使用startService()激活Service组件,并且,将自定义的ResultReceiver对象封装到用于激活IntentService的Intent对象中
4. 在IntentService的onStartCommand()方法中,通过参数Intent获取ResultReceiver对象
5. 在IntentService的onHandleIntent()方法中,在需要向Activity提交数据时,调用ResultReceiver的send()方法,发送数据
6. 在自定义的ResultReceiver类中,重写onReceiveResult()方法获取IntentService发送过来的数据,并进行处理
【注意事项】
1. IntentService中,重写生命周期方法必须确保super.xxxx()是存在,即保留调用父类的对应的方法
2. IntentService必须有无参数的构造方法
3. IntentService应该是使用startService激活的
4. 当使用自定义的ResultReceiver时,在IntentService中,必须将对象声明为ResultReceiver,而不可以是自定义的数据类型

1public class WorkService extends IntentService { 2    private ResultReceiver rr; 3 4    public WorkService() { 5        super(""); 6    } 7     8    @Override 9    public int onStartCommand(Intent intent, int flags, int startId) { 10        rr = intent.getParcelableExtra("receiver"); 11        return super.onStartCommand(intent, flags, startId); 12    } 13     14    public static final int CODE_UPDATE_PROGRESS = 1; 15    public static final String KEY_PROGRESS = "progress"; 16 17    @Override 18    protected void onHandleIntent(Intent intent) { 19        Bundle resultData = new Bundle(); 20        for (int i = 1; i <= 100; i++) { 21            Log.d("tag", "Thread id=" + Thread.currentThread().getId() + ", i=" + i); 22             23            resultData.putInt(KEY_PROGRESS, i); 24            rr.send(CODE_UPDATE_PROGRESS, resultData); 25             26            try { 27                Thread.sleep(50); 28            } catch (InterruptedException e) { 29                e.printStackTrace(); 30            } 31        } 32    } 33 34} 35 36public class MainActivity extends Activity implements View.OnClickListener { 37    private Button btnStart; 38    private ProgressBar progressBar; 39    private Handler handler; 40 41    @Override 42    protected void onCreate(Bundle savedInstanceState) { 43        super.onCreate(savedInstanceState); 44        setContentView(R.layout.activity_main); 45         46        btnStart = (Button) findViewById(R.id.button1); 47        progressBar = (ProgressBar) findViewById(R.id.progressBar1); 48         49        btnStart.setOnClickListener(this); 50         51        handler = new Handler(); 52    } 53 54    @Override 55    public void onClick(View v) { 56        Intent intent = new Intent(this, WorkService.class); 57        ResultReceiver rr = new InnerResultReceiver(handler); 58        intent.putExtra("receiver", rr); 59        startService(intent); 60    } 61     62    private class InnerResultReceiver extends ResultReceiver { 63 64        public InnerResultReceiver(Handler handler) { 65            super(handler); 66        } 67 68        @Override 69        protected void onReceiveResult(int resultCode, Bundle resultData) { 70            if(resultCode == WorkService.CODE_UPDATE_PROGRESS) { 71                int progress = resultData.getInt(WorkService.KEY_PROGRESS); 72                progressBar.setProgress(progress); 73            } 74        } 75         76    } 77 78}

异步任务(AsyncTask)
----------------------------------
AsyncTask是抽象类,需要自定义类继承并现实。
AsyncTask是集成了后台执行任务、更新进度、处理结果的一个工具,开发者在使用时无须关注子线程与主线程通信的问题。
当存在多个AsyncTask时,多个任务会依次执行。】
【AsyncTask中的泛型】
当继承自AsycnTask时,需要指定3个数据类型:
1. Prarams:参数的类型,即执行任务时需要提供的参数的数据类型,在实际执行,该参考表现为可变/变长参数
2. Progress:进度的类型,即执行任务期间是否需要提交进度,如果需要,则表现为表示进度的数据类型,例如Integer、Float等
3. Result:结果的类型,即执行任务完成后是否需要处理结果,如果需要,则表现为结果的数据类型,例如加载/下载图片时可以使用Bitmap表示该类型
【AsyncTask中的方法】
1. doInBackground():执行任务的方法,应该将具体执行的任务的相关代码编写在这个方法中,该方法默认是运行在子线程的,所以,不需要另行创建线程
2. publishProgress()与onProgressUpdate():在doInBackground中可以通过调用 publishProgress()提交进度,然后,重写onProgressUpdate()方法对进度的更新进行处 理,onProgressUpdate()默认是运行在主线程的,所以可以直接处理与UI相关的操作
3. onPostExecute():处理任务的结果,与onProgressUpdate()相同,该方法是运行在主线程的。
【注意】
由于AsyncTask是依次执行的,在需要多个任务同时开始执行,且互相不彼此影响时,最多只能有1个任务是通过AsyncTask实现的,其它都应该使用线程、消息机制来实现。

        // 判断Picture对象中是否存在Bitmap数据
        // 如果存在
        //     直接将Bitmap显示在ImageView
        // 如果不存在
        //     开启异步任务加载图片的Bitmap并显示在ImageView
        if(pic.getBitmap() != null) {
            holder.image.setImageBitmap(pic.getBitmap());
        } else {
            // 开启异步任务加载图片的Bitmap并显示在ImageView
            // 关于异步任务
            // 1. 在子线程中加载图片,得到图片的Bitmap(需要图片路径)
            // 2. 不需要更新进度
            // 3. 在主线程中显示图片(需要Bitmap,表现为子线程任务的返回值,还需要ImageView)
            // 小结:在执行任务之前,需要提供图片路径、显示图片的ImageView这2个参数,可以使用自定义的任务类的构造方法传递
            // 关于异步任务的泛型:
            // 1. 参数类型:Void
            // 2. 进度类型:Void
            // 3. 结果类型:Bitmap
        }

1    @Override 2    public void onClick(View v) { 3        new UpdateProgressTask().execute(); 4    } 5 6    private class UpdateProgressTask extends AsyncTask<String, Integer, Bitmap> { 7 8        @Override 9        protected Bitmap doInBackground(String... params) { 10            for (int i = 1; i <= 100; i++) { 11                Log.d("tag", "Thread id=" + Thread.currentThread().getId() + ", i=" + i); 12                 13                try { 14                    Thread.sleep(50); 15                } catch (InterruptedException e) { 16                    e.printStackTrace(); 17                } 18            } 19            return null; 20        } 21 22    }
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

IntentService类 和 异步任务(AsyncTask) - HelloWorld