Android Service总结05 之IntentService

 

版本

版本说明

发布时间

发布人

V1.0

添加了IntentService的介绍和示例

2013-03-17

Skywang

  1.  

1 IntentService介绍

IntentService继承与Service,它最大的特点是对服务请求逐个进行处理。当我们要提供的服务不需要同时处理多个请求的时候,可以选择继承IntentService。

IntentService有以下特点:

(1)  它创建了一个独立的工作线程来处理所有的通过onStartCommand()传递给服务的intents。

(2)  创建了一个工作队列,来逐个发送intent给onHandleIntent()。

(3)  不需要主动调用stopSelft()来结束服务。因为,在所有的intent被处理完后,系统会自动关闭服务。

(4)  默认实现的onBind()返回null

(5)  默认实现的onStartCommand()的目的是将intent插入到工作队列中。

继承IntentService的类至少要实现两个函数:构造函数和onHandleIntent()函数。要覆盖IntentService的其它函数时,注意要通过super调用父类的对应的函数。


2 IntentService示例

示例说明:编写一个activity,包含2个按钮和1个进度条,2个按钮分别是开始按钮、结束按钮。点击“开始”按钮:进度条开始加载;“开始”变成“重启”按钮;显示“结束”按钮(默认情况,“结束”按钮是隐藏状态)。

IntentService的示例包括2个类:

IntentServiceSub.java  —— 继承IntentService,并新建一个线程,用于每隔200ms将一个数字+2,并通过广播发送出去。

IntentServiceTest.java —— 启动IntentServiceSub服务,接收它发送的广播,并根据广播中的数字值来更新进度条。

IntentServiceSub.java的内容如下:

  1. package com.test;
  2.  
  3. import android.app.IntentService;
  4. import android.content.Intent;
  5. import android.util.Log;
  6.  
  7. import java.lang.Thread;
  8. /**
  9. * @desc IntentService的实现类:每隔200ms将一个数字+2并通过广播发送出去
  10. * @author skywang
  11. *
  12. */
  13. public class IntentServiceSub extends IntentService {
  14. private static final String TAG = "skywang-->IntentServiceTest";
  15.  
  16. // 发送的广播对应的action
  17. private static final String COUNT_ACTION = "com.test.COUNT_ACTION";
  18.  
  19. // 线程:用来实现每隔200ms发送广播
  20. private static CountThread mCountThread = null;
  21. // 数字的索引
  22. private static int index = 0;
  23.  
  24. public IntentServiceSub() {
  25. super("IntentServiceSub");
  26. Log.d(TAG, "create IntentServiceSub");
  27. }
  28.  
  29. @Override
  30. public void onCreate() {
  31. Log.d(TAG, "onCreate");
  32. super.onCreate();
  33. }
  34.  
  35. @Override
  36. public void onDestroy() {
  37. Log.d(TAG, "onDestroy");
  38. super.onDestroy();
  39. }
  40.  
  41. @Override
  42. protected void onHandleIntent(Intent intent) {
  43. Log.d(TAG, "onHandleIntent");
  44. // 非首次运行IntentServiceSub服务时,执行下面操作
  45. // 目的是将index设为0
  46. if ( mCountThread != null) {
  47. index = 0;
  48. return;
  49. }
  50.  
  51. // 首次运行IntentServiceSub时,创建并启动线程
  52. mCountThread = new CountThread();
  53. mCountThread.start();
  54. }
  55.  
  56. private class CountThread extends Thread {
  57. @Override
  58. public void run() {
  59. index = 0;
  60. try {
  61. while (true) {
  62. // 将数字+2,
  63. index += 2;
  64.  
  65. // 将index通过广播发送出去
  66. Intent intent = new Intent(COUNT_ACTION);
  67. intent.putExtra("count", index);
  68. sendBroadcast(intent);
  69. // Log.d(TAG, "CountThread index:"+index);
  70.  
  71. // 若数字>=100 则退出
  72. if (index >= 100) {
  73. if ( mCountThread != null)
  74. mCountThread = null;
  75.  
  76. return ;
  77. }
  78.  
  79. // 200ms
  80. this.sleep(200);
  81. }
  82. } catch (InterruptedException e) {
  83. e.printStackTrace();
  84. }
  85. }
  86. }
  87. }

IntentServiceTest.java的内容如下:

  1. package com.test;
  2.  
  3. import android.app.Activity;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.widget.Button;
  8. import android.widget.ProgressBar;
  9. import android.content.Intent;
  10. import android.content.IntentFilter;
  11. import android.content.Context;
  12. import android.content.BroadcastReceiver;
  13. import android.util.Log;
  14.  
  15. /**
  16. * @desc 创建一个activity,包含2个按钮(开始/结束)和1个ProgressBar
  17. * 点击“开始”按钮,显示“结束”按钮,并启动ProgressBar。
  18. * 点击“结束”按钮,结束ProgressBar的进度更新
  19. * @author skywang
  20. *
  21. */
  22. public class IntentServiceTest extends Activity {
  23. /** Called when the activity is first created. */
  24. private static final String TAG = "skywang-->IntentServiceTest";
  25.  
  26. private static final String COUNT_ACTION = "com.test.COUNT_ACTION";
  27. private CurrentReceiver mReceiver;
  28. private Button mStart = null;
  29. private Button mStop = null;
  30. private Intent mIntent = null;
  31. private Intent mServiceIntent = new Intent("com.test.subService");
  32. private ProgressBar mProgressBar = null;
  33. @Override
  34. public void onCreate(Bundle savedInstanceState) {
  35. super.onCreate(savedInstanceState);
  36. setContentView(R.layout.intent_service_test);
  37.  
  38. mStart = (Button) findViewById(R.id.start);
  39. mStart.setOnClickListener(new View.OnClickListener() {
  40.  
  41. @Override
  42. public void onClick(View arg0) {
  43. Log.d(TAG, "click start button");
  44. // 显示“结束”按钮
  45. mStop.setVisibility(View.VISIBLE);
  46. // 将“开始”按钮更名为“重启”按钮
  47. mStart.setText(R.string.text_restart);
  48. // 启动服务,用来更新进度
  49. if (mServiceIntent == null)
  50. mServiceIntent = new Intent("com.test.subService");
  51. startService(mServiceIntent);
  52. }
  53. });
  54.  
  55. mStop = (Button) findViewById(R.id.stop);
  56. mStop.setOnClickListener(new View.OnClickListener() {
  57.  
  58. @Override
  59. public void onClick(View arg0) {
  60. Log.d(TAG, "click stop button");
  61. if (mServiceIntent != null) {
  62. // 结束服务。
  63. // 注意:实际上这里并没有起效果。因为IntentService的特性所致。
  64. // IntentService的声明周期特别段,在startService()启动后,立即结束;所以,
  65. // 再调用stopService()实际上并没有起作用,因为服务已经结束!
  66. stopService(mServiceIntent);
  67. mServiceIntent = null;
  68. }
  69. }
  70. });
  71. mStop.setVisibility(View.INVISIBLE);
  72.  
  73. mProgressBar = (ProgressBar) findViewById(R.id.pbar_def);
  74. // 隐藏进度条
  75. mProgressBar.setVisibility(View.INVISIBLE);
  76.  
  77. // 动态注册监听COUNT_ACTION广播
  78. mReceiver = new CurrentReceiver();
  79. IntentFilter filter = new IntentFilter();
  80. filter.addAction(COUNT_ACTION);
  81. this.registerReceiver(mReceiver, filter);
  82. }
  83.  
  84. @Override
  85. public void onDestroy(){
  86. super.onDestroy();
  87.  
  88. if(mIntent != null)
  89. stopService(mIntent);
  90.  
  91. if(mReceiver != null)
  92. this.unregisterReceiver(mReceiver);
  93. }
  94.  
  95. /**
  96. * @desc 更新进度条
  97. * @param index
  98. */
  99. private void updateProgressBar(int index) {
  100. int max = mProgressBar.getMax();
  101.  
  102. if (index < max) {
  103. // 显示进度条
  104. mProgressBar.setVisibility(View.VISIBLE);
  105. mProgressBar.setProgress(index);
  106. } else {
  107. // 隐藏进度条
  108. mProgressBar.setVisibility(View.INVISIBLE);
  109. // 隐藏“结束”按钮
  110. mStop.setVisibility(View.INVISIBLE);
  111. // 将“重启”按钮更名为“开始”按钮
  112. mStart.setText(R.string.text_start);
  113. }
  114. // Log.d(TAG, "progress : "+mProgressBar.getProgress()+" , max : "+max);
  115. }
  116.  
  117. /**
  118. * @desc 广播:监听COUNT_ACTION,获取索引值,并根据索引值来更新进度条
  119. * @author skywang
  120. *
  121. */
  122. private class CurrentReceiver extends BroadcastReceiver {
  123. @Override
  124. public void onReceive(Context context, Intent intent) {
  125. String action = intent.getAction();
  126. if (COUNT_ACTION.equals(action)) {
  127. int index = intent.getIntExtra("count", 0);
  128. updateProgressBar(index);
  129. }
  130. }
  131. }
  132. }

layout文件intent_service_test.xml的内容如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. >
  7.  
  8. <LinearLayout
  9. android:orientation="horizontal"
  10. android:layout_width="wrap_content"
  11. android:layout_height="wrap_content"
  12. >
  13. <Button
  14. android:id="@+id/start"
  15. android:layout_width="wrap_content"
  16. android:layout_height="wrap_content"
  17. android:text="@string/text_start"
  18. />
  19. <Button
  20. android:id="@+id/stop"
  21. android:layout_width="wrap_content"
  22. android:layout_height="wrap_content"
  23. android:text="@string/text_stop"
  24. />
  25.  
  26. </LinearLayout>
  27.  
  28. <ProgressBar
  29. android:id="@+id/pbar_def"
  30. android:layout_width="match_parent"
  31. android:layout_height="wrap_content"
  32. style="@android:style/Widget.ProgressBar.Horizontal"
  33. android:max="100"
  34. android:progress="0"
  35. />
  36. </LinearLayout>

manifest代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.test"
  4. android:versionCode="1"
  5. android:versionName="1.0">
  6. <uses-sdk android:minSdkVersion="8" />
  7.  
  8. <application android:icon="@drawable/icon" android:label="@string/app_name">
  9. <activity
  10. android:name=".IntentServiceTest"
  11. android:screenOrientation="portrait"
  12. android:label="@string/app_name">
  13. <intent-filter>
  14. <action android:name="android.intent.action.MAIN" />
  15. <category android:name="android.intent.category.LAUNCHER" />
  16. </intent-filter>
  17. </activity>
  18.  
  19. <service android:name=".IntentServiceSub">
  20. <intent-filter>
  21. <action android:name="com.test.subService" />
  22. </intent-filter>
  23. </service>
  24.  
  25. </application>
  26. </manifest>

点击下载:示例源代码

程序截图如下:


更多service内容:

Android Service总结01 目录

Android Service总结02 service介绍

Android Service总结03 之被启动的服务 -- Started Service

Android Service总结04 之被绑定的服务 -- Bound Service

Android Service总结05 之IntentService

Android Service总结06 之AIDL


参考文献

1,Android API文档: http://developer.android.com/guide/components/services.html

Android Service总结05 之IntentService的更多相关文章

  1. Android Service总结06 之AIDL

    Android Service总结06 之AIDL 版本 版本说明 发布时间 发布人 V1.0 初始版本 2013-04-03 Skywang           1 AIDL介绍 AIDL,即And ...

  2. Android Service总结04 之被绑定的服务 -- Bound Service

    Android Service总结04 之被绑定的服务 -- Bound Service 版本 版本说明 发布时间 发布人 V1.0 添加了Service的介绍和示例 2013-03-17 Skywa ...

  3. Android Service总结01 目录

    Android Service总结01 目录 1 Android Service总结01 目录 2 Android Service总结02 service介绍 介绍了“4种service 以及 它们的 ...

  4. Android Service总结02 service介绍

    Android Service总结02 service介绍 版本 版本说明 发布时间 发布人 V1.0 介绍了Service的种类,常用API,生命周期等内容. 2013-03-16 Skywang ...

  5. Android Service总结03 之被启动的服务 -- Started Service

    Android Service总结03 之被启动的服务 -- Started Service 版本 版本说明 发布时间 发布人 V1.0 添加了Service的介绍和示例 2013-03-17 Sky ...

  6. android服务Service(上)- IntentService

    Android学习笔记(五一):服务Service(上)- IntentService 对于需要长期运行,例如播放音乐.长期和服务器的连接,即使已不是屏幕当前的activity仍需要运行的情况,采用服 ...

  7. android service 的各种用法(IPC、AIDL)

    http://my.oschina.net/mopidick/blog/132325 最近在学android service,感觉终于把service的各种使用场景和用到的技术整理得比较明白了,受益颇 ...

  8. 2、android Service 详细用法

    定义一个服务 在项目中定义一个服务,新建一个ServiceTest项目,然后在这个项目中新增一个名为MyService的类,并让它继承自Service,完成后的代码如下所示: ? 1 2 3 4 5 ...

  9. Android组件系列----Android Service组件深入解析

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

随机推荐

  1. 20155301PC平台逆向破解

    20155301PC平台逆向破解 1.掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码 NOP:NOP指令即"空指令".执行到NOP指令时,CPU什么也不做,仅仅当 ...

  2. 20155338《网络对抗》Exp3 免杀原理与实践

    20155338<网络对抗>Exp3 免杀原理与实践 实验过程 一.免杀效果参考基准 Kali使用上次实验msfvenom产生后门的可执行文件,上传到老师提供的网址http://www.v ...

  3. python 回溯法 子集树模板 系列 —— 9、旅行商问题(TSP)

    问题 旅行商问题(Traveling Salesman Problem,TSP)是旅行商要到若干个城市旅行,各城市之间的费用是已知的,为了节省费用,旅行商决定从所在城市出发,到每个城市旅行一次后返回初 ...

  4. 利用fiddler core api 拦截修改 websocket 数据

    一般的中间人攻击基本都是拦截修改普通的http协议里面的内容,而对于怎么拦截修改websocket协议传输的内容好像都没有多少介绍. talk is cheap show me the code us ...

  5. ReactJS实用技巧(2):从新人大坑——表单组件来看State

    不太清楚有多少初学React的同学和博主当时一样,在看完React的生命周期.数据流之后觉得已经上手了,甩开文档啪啪啪的开始敲了起来.结果...居然被一个input标签给教做人了. 故事是这样的:首先 ...

  6. Android 测试之Monkey

    一.什么是Monkey Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中.它向系统发送伪随机的用户事件流(如按键输入.触摸屏输入.手势输入等),实现对正在开发的应用程序进 ...

  7. 关于UGUI不拦截射线的方法

    起因:开发游戏,要在设置界面里给一个设置项添加一个东西解释这个项是干啥的,要求鼠标移到文字上的时候显示一个弹窗差不多的东西,见动图,鼠标移开会消失.但是当我移动鼠标到弹窗上的时候,UGUI会发射一根射 ...

  8. CEPH LIO iSCSI Gateway

    参考文档: Ceph Block Device:http://docs.ceph.com/docs/master/rbd/ CEPH ISCSI GATEWAY:http://docs.ceph.co ...

  9. 红黑树插入与删除完整代码(dart语言实现)

    之前分析了红黑树的删除,这里附上红黑树的完整版代码,包括查找.插入.删除等.删除后修复实现了两种算法,均比之前的更为简洁.一种是我自己的实现,代码非常简洁,行数更少:一种是Linux.Java等源码版 ...

  10. Notes of Daily Scrum Meeting(12.16)

    最近好几门课的大作业都到了要截止的时候了,好多天队员们都抽不出来时间做软工的项目了,这样确实 和我们的计划出入很大,不过希望老师谅解,三门课程设计确实压力很大. 今天的团队任务总结如下: 团队成员 今 ...