不管是何种Service,它默认都是在应用程序的主线程(亦即UI线程)中运行的。所以,如果你的Service将要运行非常耗时或者可能被阻塞的操作时,你的应用程序将会被挂起,甚至会出现ANR错误。为了避免这一问题,你应该在Service中重新启动一个新的线程来进行这些操作。现有两种方法共大家参考:
① 直接在Service的onStartCommand()方法中重启一个线程来执行,如:
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- MyServiceActivity.updateLog(TAG + " ----> onStartCommand()");
- new Thread(new Runnable() {
- @Override
- public void run() {
- // 此处进行耗时的操作,这里只是简单地让线程睡眠了1s
- try {
- Thread.sleep(1000);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- return START_STICKY;
- }
② Android SDK 中为我们提供了一个现成的Service类来实现这个功能,它就是IntentService,它主要负责以下几个方面:
- Creates a default worker thread that executes all intents delivered to
onStartCommand()
separate from your application's main thread.
生成一个默认的且与主线程互相独立的工作者线程来执行所有传送至 onStartCommand() 方法的Intetnt
- Creates a work queue that passes one intent at a time to your
onHandleIntent()
implementation, so you never have to worry about multi-threading.
生成一个工作队列来传送Intent对象给你的onHandleIntent()方法,同一时刻只传送一个Intent对象,这样一来,你就不必担心多线程的问题。
- Stops the service after all start requests have been handled, so you never have to call
stopSelf()
.
在所有的请求(Intent)都被执行完以后会自动停止服务,所以,你不需要自己去调用stopSelf()方法来停止该服务
- Provides default implementation of
onBind()
that returns null.
提供了一个onBind()方法的默认实现,它返回null
- Provides a default implementation of
onStartCommand()
that sends the intent to the work queue and then to youronHandleIntent()
implementation
提供了一个onStartCommand()方法的默认实现,它将Intent先传送至工作队列,然后从工作队列中每次取出一个传送至onHandleIntent()方法,在该方法中对Intent对相应的处理
以上,英文来自官方SDK,中文为我所译。
从以上看来,你所需要做的就是实现 onHandleIntent() 方法,在该方法内实现你想进行的操作。另外,继承IntentService时,你必须提供一个无参构造函数,且在该构造函数内,你需要调用父类的构造函数,如下:
- public HelloIntentService() {
- super("HelloIntentService");
- }
下面给出一例,来解释一下:
- // activity 的onCreate()
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- startSer1 = (Button) findViewById(R.id.startSer1);
- stopSer1 = (Button) findViewById(R.id.stopSer1);
- startSer2 = (Button) findViewById(R.id.startSer2);
- stopSer2 = (Button) findViewById(R.id.stopSer2);
- log = (TextView) findViewById(R.id.log);
- logView = (ScrollView) findViewById(R.id.logView);
- startSer1.setOnClickListener(btnListener);
- stopSer1.setOnClickListener(btnListener);
- startSer2.setOnClickListener(btnListener);
- stopSer2.setOnClickListener(btnListener);
- intent = new Intent(MyServiceActivity.this, IntentServiceDemo.class);
- // 打印出主线程的ID
- long id = Thread.currentThread().getId();
- updateLog(TAG + " ----> onCreate() in thread id: " + id);
- }
- // service 代码
- package com.archer.rainbow;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import android.app.IntentService;
- import android.content.Intent;
- public class IntentServiceDemo extends IntentService {
- private static final String TAG = "IntentServiceDemo";
- private static final SimpleDateFormat SDF_DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss.SSS");
- public IntentServiceDemo() {
- super(TAG);
- MyServiceActivity.updateLog(TAG + " ----> constructor");
- }
- @Override
- public void onCreate() {
- super.onCreate();
- // 打印出该Service所在线程的ID
- long id = Thread.currentThread().getId();
- MyServiceActivity.updateLog(TAG + " ----> onCreate() in thread id: "
- + id);
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- MyServiceActivity.updateLog(TAG + " ----> onDestroy()");
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- MyServiceActivity.updateLog(TAG + " ----> onStartCommand()");
- // 记录发送此请求的时间
- intent.putExtra("time", System.currentTimeMillis());
- return super.onStartCommand(intent, flags, startId);
- }
- @Override
- public void setIntentRedelivery(boolean enabled) {
- MyServiceActivity.updateLog(TAG + " ----> setIntentRedelivery()");
- super.setIntentRedelivery(enabled);
- }
- @Override
- protected void onHandleIntent(Intent intent) {
- // 打印出处理intent所用的线程的ID
- long id = Thread.currentThread().getId();
- MyServiceActivity.updateLog(TAG
- + " ----> onHandleIntent() in thread id: " + id);
- long time = intent.getLongExtra("time", 0);
- Date date = new Date(time);
- try {
- // 打印出每个请求对应的触发时间
- MyServiceActivity.updateLog(TAG
- + " ----> onHandleIntent(): 下载文件中..." + SDF_DATE_FORMAT.format(date));
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
应用启动时,界面如下:
从此图可以看出,主线程(UI线程)的ID是1。接,连续点击三次Start Service 1 按钮,得如下画面:
从此图中可以看出,IntentServiceDemo的onCreate()所处的线程ID仍为1,说明它是在主线程中被执行的,且只被执行一次。然后,我每点击一次按钮,它都会触发一下onStartCommand()方法。仔细看第二次与第三次的onCommand()方法以及onHandleIntent()打印出来的语句,你会发现,第二、三两次点击按钮与第一次点击按钮的时间是没有超过3秒钟的,它们是连续被执行的,这说明了什么呢?说明,在第一个intent被处理时(即onHandleIntent()处于运行中),该Service仍然可以接受新的请求,但接受到新的请求后并没有立即执行,而是将它们放入了工作队列中,等待被执行。
这就是 IntentService 的简单用法。但你若是想在Service中让多个线程并发的话,就得另想法子喽。比如,使用第一种方法,在Service内部起多个线程,但是这样的话,你可要处理好线程的同步哦~~~
相关推荐
service中1需要手动开启子线程2服务开启之后会一直运行,需要手动调用stopService();或者stopSelf(); intentService是一种异步(子线程)、自动停止的服务,这个例子测试IntentService的特征
3. 在ServiceDemoActivity.java中都调用了两个service,调用service自行屏蔽调用IntentServiceServie,调用IntentServiceServie自行屏蔽调用service。 4. 仅仅是个例子,对比这个service和IntentServiceServie的区别...
主要介绍了Android系统中Service和IntentService的区别,与普通的服务相比,IntentService可以开启单独的线程来处理intent请求,需要的朋友可以参考下
介绍service和intentservice的使用和其中应该注意的部分
NULL 博文链接:https://zhanglimijavaeye.iteye.com/blog/1881599
Android IntentService详解 一、IntentService简介 IntentService是Service的子类,比普通的Service增加了额外的功能。先看Service本身存在两个问题: Service不会专门启动一条单独的进程,Service与它所在...
再开始之前我们还是先介绍下service吧:此处用的是IntentService,至于和常规的service有什么区别呢? 有了Service为什么还要有个IntentService呢? 原因如下: 1)Service默认运行在主线程中,IntentService运行在一个...
IntentService简单demo,对应博文 http://blog.csdn.net/tianmi1988/article/details/50520339
IntentService基本使用方法Demo
Android中的IntentService是继承自Service类的,在我们讨论IntentService之前,我们先想一下Service的特点: Service的回调方法(onCreate、onStartCommand、onBind、onDestroy)都是运行在主线程中的。当我们通过start...
Android 中IntentService的简单应用
对于有写工作,我们需要在后台进行,这里主要介绍了使用IntentService轻松实现模拟上传图片的例子。对于IntentServixce和Service扩展类的使用区别,大家可以自行去了解研究一下。
Android四大组件——Service后台服务、前台服务、IntentService、跨进程服务、无障碍服务、系统服务
本篇文章主要介绍了Android 基于IntentService的文件下载的示例代码,具有一定的参考价值,有兴趣的可以了解一下
Android说明Service生命周期的代码例子。用于演示Service组件从创建到销毁的完整生命周期,以及IntentService的使用例子。
主要介绍了Android中使用IntentService创建后台服务实例,IntentService提供了在单个后台线程运行操作的简单结构,需要的朋友可以参考下
Android_Blog_Demos 存储CSDN博客的一些源码...Android IntentService完全解析 当Service遇到Handler 详细 Android 高清加载巨图方案 拒绝压缩图片 ViewDragHelper实战 自己打造Drawerlayout Android UI性能优化实