`
Rainbow702
  • 浏览: 1076707 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类

android service 之二(IntentService)

阅读更多

不管是何种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 your onHandleIntent() 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内部起多个线程,但是这样的话,你可要处理好线程的同步哦~~~ 

     

    • 大小: 19.3 KB
    • 大小: 62.7 KB
    9
    2
    分享到:
    评论
    6 楼 Rainbow702 2013-09-26  
    helonghui 写道
    good! 最后总结得很好。

    当时只是为了备忘
    5 楼 helonghui 2013-09-25  
    good! 最后总结得很好。
    4 楼 yang7162082 2013-03-27  
    很有帮助,谢谢。
    3 楼 x_h_j123 2012-08-26  
    正解决了我当前遇到的问题,thanks!
    2 楼 n70joey 2011-09-16  
    好东西!!
    1 楼 Rainbow702 2011-08-09  
    第一种方式的话,最好使用Handler,但是我对这个还不太熟,所以没怎么写啊

    相关推荐

      Android中IntentService的特征

      service中1需要手动开启子线程2服务开启之后会一直运行,需要手动调用stopService();或者stopSelf(); intentService是一种异步(子线程)、自动停止的服务,这个例子测试IntentService的特征

      service和Intentservice示例

      `Service`是Android四大组件之一(Activity、BroadcastReceiver、ContentProvider、Service),它主要用于在后台执行任务,如音乐播放、网络通信等。`Service`并没有自己的UI,因此不会占用用户界面,但会持续运行,...

      android 中的服务Service intentService例子

      总结,Service和IntentService是Android中实现后台任务的关键组件。理解它们的生命周期、使用方式和最佳实践,对于提升应用程序的稳定性和效率至关重要。在实际项目中,根据需求选择合适的服务类型,结合源码学习,...

      深入剖析Android系统中Service和IntentService的区别

      在Android开发中,Service是用于实现应用程序在后台运行的关键组件,它可以持续运行,即使用户离开...因此,理解Service和IntentService的区别以及它们各自的适用场景,对于优化Android应用的性能和用户体验至关重要。

      android service和intentService

      3. 在ServiceDemoActivity.java中都调用了两个service,调用service自行屏蔽调用IntentServiceServie,调用IntentServiceServie自行屏蔽调用service。 4. 仅仅是个例子,对比这个service和IntentServiceServie的区别...

      android service 简单实例源代码

      在Android开发中,Service是四大组件之一,它在后台运行,不与用户界面直接交互,常用于执行长时间的任务,如播放音乐、网络通信等。本篇文章将深入解析"android service 简单实例源代码",帮助你理解如何在Android...

      IntentService学习Demo

      在Android应用开发中,IntentService是一个非常重要的组件,它继承自Service,并且简化了后台服务的处理流程。IntentService主要用于执行单一的任务或者一系列串行任务,而不会长时间占用主线程,提高了应用的响应...

      Android—IntentService

      IntentService是Android系统提供的一种特殊服务,用于在后台执行单线程的任务,处理异步请求。它非常适合执行一次性任务,如网络请求、数据同步或耗时计算,且不会阻塞UI线程。IntentService的使用既简单又高效,...

      IntentService

      IntentService是Android系统中一种特殊的Service,它是Service的子类,设计用于在后台执行单一的任务,然后自动停止服务,不需要手动调用stopSelf()。IntentService的使用极大地简化了后台异步任务处理,并且保证了...

      Android中的IntentService简介.pdf

      IntentService是Android操作系统中一种特殊的Service子类,它主要用于处理那些需要后台运行的单个任务,比如网络请求、数据同步等。与普通的Service相比,IntentService具有更好的线程管理和任务调度机制,使得...

      android service 之一 (start service)

      在Android应用开发中,Service是四大组件之一,它在后台执行长时间运行的操作,不与用户交互。本篇文章将深入探讨Android中的Start Service,这是一种启动Service的方式,它关注的是任务的启动而不是用户界面的反馈...

      android service

      在Android系统中,Service是一种非常重要的组件,它允许应用程序在后台长时间运行操作,即使用户界面已经关闭。Service主要用于执行长时间运行的任务,如播放音乐、网络通信或者定期数据同步。本篇我们将深入探讨...

      android service下载资源,同时解压资源

      - Service是Android四大组件之一,用于在后台执行长期运行的操作,即使用户离开了应用程序,Service仍然可以继续运行。 - 创建Service需要继承`Service`类,并重写其中的关键方法,如`onStartCommand()`和`...

      android service组件与记事本

      首先,Android的Service组件主要分为两种类型:标准Service和IntentService。在这个描述中,可能是使用了标准Service,因为IntentService会自动处理工作线程并结束自身,而这里需要在用户退出时手动停止音乐播放。 ...

      Android-AndroidService下载文件

      `Service` 是Android四大组件之一(Activity、BroadcastReceiver、ContentProvider、Service),它主要用于执行长时间运行的操作,例如音乐播放、后台数据同步或像本例中的文件下载。服务没有用户界面,因此它不会...

      android学习之Service启动1

      在Android开发中,Service是四大组件之一,它用于在后台执行长时间运行的操作,而不与用户交互。本篇文章将深入探讨“android学习之Service启动1”的主题,主要关注Service的启动方式及其基本用法。 首先,Service...

      Android IntentService详解及使用实例

      Android IntentService详解 一、IntentService简介 IntentService是Service的子类,比普通的Service增加了额外的功能。先看Service本身存在两个问题:  Service不会专门启动一条单独的进程,Service与它所在...

      详解Android中IntentService的使用方法

      在Android应用开发中,IntentService是一个非常重要的组件,它继承自Service类,专门用于执行后台的单线程任务,尤其适合处理那些可能阻塞主线程的操作,如网络请求、文件下载等。IntentService的设计旨在避免主线程...

      android Service类简介

      另外,使用IntentService是一个好的实践,IntentService是Service的一个子类,它自动处理工作队列,当所有任务完成时,IntentService会自动停止自身,简化了服务的管理。 在Android开发中,Service是不可或缺的部分...

    Global site tag (gtag.js) - Google Analytics