文档章节

IntentService类 和 异步任务(AsyncTask)

 梦想家Peng
发布于 2016/03/03 14:56
字数 1326
阅读 61
收藏 3
点赞 1
评论 0

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,而不可以是自定义的数据类型


public class WorkService extends IntentService {
    private ResultReceiver rr;

    public WorkService() {
        super("");
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        rr = intent.getParcelableExtra("receiver");
        return super.onStartCommand(intent, flags, startId);
    }
    
    public static final int CODE_UPDATE_PROGRESS = 1;
    public static final String KEY_PROGRESS = "progress";

    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle resultData = new Bundle();
        for (int i = 1; i <= 100; i++) {
            Log.d("tag", "Thread id=" + Thread.currentThread().getId() + ", i=" + i);
            
            resultData.putInt(KEY_PROGRESS, i);
            rr.send(CODE_UPDATE_PROGRESS, resultData);
            
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

public class MainActivity extends Activity implements View.OnClickListener {
    private Button btnStart;
    private ProgressBar progressBar;
    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        btnStart = (Button) findViewById(R.id.button1);
        progressBar = (ProgressBar) findViewById(R.id.progressBar1);
        
        btnStart.setOnClickListener(this);
        
        handler = new Handler();
    }

    @Override
    public void onClick(View v) {
        Intent intent = new Intent(this, WorkService.class);
        ResultReceiver rr = new InnerResultReceiver(handler);
        intent.putExtra("receiver", rr);
        startService(intent);
    }
    
    private class InnerResultReceiver extends ResultReceiver {

        public InnerResultReceiver(Handler handler) {
            super(handler);
        }

        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            if(resultCode == WorkService.CODE_UPDATE_PROGRESS) {
                int progress = resultData.getInt(WorkService.KEY_PROGRESS);
                progressBar.setProgress(progress);
            }
        }
        
    }

}


异步任务(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
        }

    @Override
    public void onClick(View v) {
        new UpdateProgressTask().execute();
    }

    private class UpdateProgressTask extends AsyncTask<String, Integer, Bitmap> {

        @Override
        protected Bitmap doInBackground(String... params) {
            for (int i = 1; i <= 100; i++) {
                Log.d("tag", "Thread id=" + Thread.currentThread().getId() + ", i=" + i);
                
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }

    }



© 著作权归作者所有

共有 人打赏支持
粉丝 0
博文 34
码字总数 15605
作品 0
深圳
Android异步加载全解析之IntentService

Android异步加载全解析之IntentService 搞什么IntentService 前面我们说了那么多,异步处理都使用钦定的AsyncTask,再不济也使用的Thread,那么这个IntentService是个什么鬼。 相对与前面我们...

eclipse_xu
2015/03/31
0
0
Android 异步编程

文章作者:朱鸿,淘宝资深架构师 原文出处:http://hugozhu.myalert.info/2014/06/29/46-async-android.html Android的线程和内存模型 Android操作系统在boot后,会启动一个Zygote(受精卵)进...

鉴客
2014/07/01
1K
1
Android 源码分析(三)安卓中的线程

上一节我们一起探索了 Handler 的跨线程通信机制,这里我么趁热打铁,一举拿下 Android 中的线程。 今天我们主要探索 AsyncTask、HandlerThread、IntentService 三个类,这三个类的表现形式和...

diamond_lin
2017/12/07
0
0
《Android开发艺术探索》之Android中的线程和线程池

序言 这篇文章主要记录在学习《Android开发艺术探索》第11章的读书笔记,以备日后查用,码字不易转载请注明出处:http://www.jianshu.com/p/64db22fa9bc4 1、Android中扮演线程的有Thread 、A...

在代码下成长
2017/12/06
0
0
【学习笔记】Android的线程和线程池

除了传统的Thread以外,还包含AsyncTask、HandlerThread、以及IntentService,这三者的底层实现也是线程 AsyncTask 从实现上来说,AsyncTask封装了Thread和Handler,通过AsyncTask可以更加方...

小树coding
2016/02/29
92
0
【Bugly干货分享】Android性能优化典范之多线程篇

本文涉及的内容有:多线程并发的性能问题,介绍了 AsyncTask,HandlerThread,IntentService 与 ThreadPool 分别适合的使用场景以及各自的使用注意事项,这是一篇了解 Android 多线程编程不可...

腾讯Bugly
2016/05/23
381
1
Android面试必会知识点 - ANR详解

最近在公司出差过多,感觉自己快被废了,这时候正好有大公司给了面试机会,于是就去试试,虽然最后Tencent没有要我,但是过程中让我对Android有了更新的认知,把我的对于Android的理解又提升...

吴雨声
07/02
0
0
IntentService-你可能需要知道这些

Service作为Android四大组件之一,在我们的日常开发中占着不可或缺的一席,而轻量级的IntentService作为对Service的一个补充,也越来越收到大家的推崇,本博文就带大家来学习和分析下IntentS...

24K男
2017/09/27
0
0
android AsyncTask介绍

AsyncTask和Handler对比 1 ) AsyncTask实现的原理,和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(...

墨梅
2014/10/29
0
0
AsyncTask 的实现原理

在《Android异步处理二:使用AsyncTask异步更新UI界面》一文中,我们介绍了如何使用AsyncTask实现异步下载图片,并且更新图片到UI界面的方法。本篇我们将学习Framework层AsyncTask的实现原理...

鉴客
2011/09/17
7.5K
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Python PIPEs

https://www.python-course.eu/pipes.php https://www.tutorialspoint.com/python/os_pipe.htm

zungyiu
3分钟前
0
0
gRPC学习笔记

gRPC编程流程 1. proto文件定义 proto文件用于定义需要通过gRPC生成的接口,可以理解为接口定义文档 2. 通过构建工具生成服务基类代码-Maven或Gradle 3. 服务端开发 服务端实现类须实现通过构...

OSC_fly
22分钟前
0
0
Docker Mac (三) Dockerfile 及命令

Dockerfile 最近学习docker的时候,遇到一件怪事,关于docker镜像可能会被破坏,还不知道它会有此措施 所以需要了解构建Dockerfile的正确方法 Dockerfile是由一系列命令和参数构成的脚本,这些命...

___大侠
49分钟前
0
0
Android Studio+NDK+Cmake 移植FFmpeg-4.0.2命令行工具

一、编译 参考大神的帖子,亲测一次编译成功:https://blog.csdn.net/bobcat_kay/article/details/80889398 鉴于以前查文档的经验,这里附上编写例子的时间:2018年7月22日 我用的是ubantu,...

她叫我小渝
49分钟前
0
0
mysql创建数据库

登录MYSQL mysql -u root -p 脚本创建数据库WeChat,并制定默认的字符集是utf8mb4。 CREATE DATABASE Wechat DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci; 授权 grant all......

niithub
今天
0
0
svn: Unable to connect to a repository URL 的解决方案

错误图示: 解决办法:清除本地保存的授权信息; 1:右键点击本地文件夹,选择设置; TortoiseSVN -> Settings 2:在弹出的对话框中选择 Saved Data, 右侧选择:授权地方清理所有。 然后点确...

宁哥实战课堂
今天
1
0
sleep与wait的区别

Thread.sleep(XXX)方法消耗CPU吗? 这个知识点是我之前认识一直有错误的一个知识点,在我以前的认识里面,我一直认为Thread.sleep(1000)的这一秒钟的时间内,线程的休眠是一直占用着CPU的时间...

码代码的小司机
今天
1
0
20位活跃在Github上的国内技术大牛 leij 何小鹏 亚信

本文列举了20位在Github上非常活跃的国内大牛,看看其中是不是很多熟悉的面孔? 1. lifesinger(玉伯) Github主页: https://github.com/lifesinger 微博:@ 玉伯也叫射雕 玉伯(王保平),...

海博1600
今天
1
0
Mybatis收集配置

一、Mybatis取Clob数据 1、Mapper.xml配置 <resultMap type="com.test.User" id="user"> <result column="id" property="id"/> <result column="json_data" property="jsonData" ......

星痕2018
今天
1
0
centos7设置以多用户模式启动

1、旧版本linux系统修改inittab文件,在新版本执行vi /etc/inittab 会有以下提示 # inittab is no longer used when using systemd. # # ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON......

haha360
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部