IntentService是一个Service类。
IntentService只有1个带String参数的构造方法,因此,在自定义类继承IntentService时,须要在自定义类中显式的调用IntentService带参数的构造方法,而且将自定义类的构造方法修改成无参数的。
IntentService内部使用消息机制,利用消息队列的特性,能够依次处理多个耗时操做。
IntentService具备生命力强、一次性使用、依次处理多个耗时操做的特性。
注意:在自定义类继承IntentService时,能够重写IntentService的生命周期方法,可是,不能够删除super语句java
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
}ide
@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; } }