android: 使用 IntentService
9.5.2 使用 IntentService
话说回来,在本章一开始的时候我们就已经知道,服务中的代码都是默认运行在主线程 当中的,如果直接在服务里去处理一些耗时的逻辑,就很容易出现 ANR(Application Not Responding)的情况。
所以这个时候就需要用到 Android 多线程编程的技术了,我们应该在服务的每个具体的 方法里开启一个子线程,然后在这里去处理那些耗时的逻辑。因此,一个比较标准的服务就 可以写成如下形式:
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
// 处理具体的逻辑
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
}
但是,这种服务一旦启动之后,就会一直处于运行状态,必须调用 stopService()或者 stopSelf()方法才能让服务停止下来。所以,如果想要实现让一个服务在执行完毕后自动停止 的功能,就可以这样写:
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
// 处理具体的逻辑
stopSelf();
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
}
虽说这种写法并不复杂,但是总会有一些程序员忘记开启线程,或者忘记调用 stopSelf() 方法。为了可以简单地创建一个异步的、会自动停止的服务,Android 专门提供了一个 IntentService 类,这个类就很好地解决了前面所提到的两种尴尬,下面我们就来看一下它的 用法。
新建一个 MyIntentService 类继承自 IntentService,代码如下所示:
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService"); // 调用父类的有参构造函数
}
@Override
protected void onHandleIntent(Intent intent) {
// 打印当前线程的id
Log.d("MyIntentService", "Thread id is " + Thread.currentThread(). getId());
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyIntentService", "onDestroy executed");
}
}
这里首先是要提供一个无参的构造函数,并且必须在其内部调用父类的有参构造函数。
然后要在子类中去实现 onHandleIntent()这个抽象方法,在这个方法中可以去处理一些具体的 逻辑,而且不用担心 ANR 的问题,因为这个方法已经是在子线程中运行的了。这里为了证 实一下,我们在 onHandleIntent()方法中打印了当前线程的 id。另外根据 IntentService 的特性, 这个服务在运行结束后应该是会自动停止的,所以我们又重写了 onDestroy()方法,在这里也 打印了一行日志,以证实服务是不是停止掉了。
接下来修改 activity_main.xml 中的代码,加入一个用于启动 MyIntentService 这个服务的 按钮,如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical" >
……
<Button android:id="@+id/start_intent_service" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Start IntentService" />
</LinearLayout>
然后修改 MainActivity 中的代码,如下所示:
public class MainActivity extends Activity implements OnClickListener {
……
private Button startIntentService;
@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
……
startIntentService = (Button) findViewById(R.id.start_intent_service);
startIntentService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
……
case R.id.start_intent_service:
// 打印主线程的id
Log.d("MainActivity", "Thread id is " + Thread.currentThread().
getId());
Intent intentService = new Intent(this, MyIntentService.class);
startService(intentService);
break;
default:
break;
}
}
}
可以看到,我们在 Start IntentService 按钮的点击事件里面去启动 MyIntentService 这个服 务,并在这里打印了一下主线程的 id,稍后用于和 IntentService 进行比对。你会发现,其实 IntentService 的用法和普通的服务没什么两样。
最后仍然不要忘记,服务都是需要在 AndroidManifest.xml 里注册的,如下所示:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.servicetest"
android:versionCode="1"
android:versionName="1.0" >
……
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" >
……
<service android:name=".MyIntentService"></service>
</application>
</manifest>
现在重新运行一下程序,界面如图 9.13 所示。

图 9.13
点击 Start IntentService 按钮后,观察 LogCat 中的打印日志,如图 9.14 所示。

图 9.14
可以看到,不仅 MyIntentService 和 MainActivity 所在的线程 id 不一样,而且 onDestroy() 方法也得到了执行,说明 MyIntentService 在运行完毕后确实自动停止了。集开启线程和自动 停止于一身,IntentService 还是博得了不少程序员的喜爱。
android: 使用 IntentService的更多相关文章
- android基础---->IntentService的使用
这一篇博客,我们开始前台服务与IntentServie源码分析的学习,关于service的生命周期及其简单使用,请参见我的博客:(android基础---->service的生命周期) 目录导航 ...
- Android开发--IntentService的用法,你错过了什么
Android开发--IntentService的用法,你错过了什么 . 本文链接:https://blog.csdn.net/smbroe/article/details/45009721 Inte ...
- Android中IntentService与Service
Android中的Service是用于后台服务的,当应用程序被挂到后台的时候,问了保证应用某些组件仍然可以工作而引入了Service这个概念,那么这里面要强调的是Service不是独立的进程,也不是独 ...
- android 中IntentService的使用场景
IntentService是继承并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统的Service一样,同时,当任务执行 ...
- android 中IntentService的作用及使用
IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service一样,同 ...
- 【Android】IntentService & HandlerThread源码解析
一.前言 在学习Service的时候,我们一定会知道IntentService:官方文档不止一次强调,Service本身是运行在主线程中的(详见:[Android]Service),而主线程中是不适合 ...
- Android中IntentService的原理及使用
在Android开发中,我们或许会碰到这么一种业务需求,一项任务分成几个子任务,子任务按顺序先后执行,子任务全部执行完后,这项任务才算成功.那么,利用几个子线程顺序执行是可以达到这个目的的,但是每个线 ...
- [Android Pro] Android中IntentService的原理及使用
转载自:http://blog.csdn.net/ryantang03/article/details/8146154 在Android开发中,我 们或许会碰到这么一种业务需求,一项任务分成几个子任务 ...
- Android中IntentService详解
简单说,IntentService是继承于Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统Service ...
随机推荐
- [MongoDB]Mongodb攻略
-------------------------------------------------------------------------------------------- [基础] 1. ...
- Windows通用应用开发手记-Behavior SDK概述
随着Visual Studio 2013的发布,New Behavior SDK也一起出现了.和Expression Blend SDK相似,包括各种内置行为(behavior和action),可以用 ...
- ubuntu工具积累
1.sudo apt-get install terminator一款可以切分终端窗口的工具 a.在系统>键盘>快捷键修该ctrl+alt+t快捷应用为terminator,其他的快捷键同 ...
- Reapter控件的特殊使用:使用EVAL调取asp:Repeater里面绑定的值来进行判断 根据从数据库获取的数据进行判断 ,进而显示成想要的内容
1.这个判断的过程你可以写在后台,如先在后台写一个public类型的方法:public bool CheckAduit(string code){ //根据你传入的code来判断,并返回true或者f ...
- unity --项目总结
最近做的unity的项目涉及到的问题如下: 1.绘制折线图问题: 起初利用的unity自带的linerender组件,这种方法绘制的线不均匀,效果不好.然后又利用画线插件Ves……开头的那个,结果那个 ...
- 为什么要学习和掌握Linux?
总结:从“为什么要学习和掌握Linux”开始,James阐述原因和理由:规划自己的目标: 为什么要学习和掌握Linux?——在读书时,如果看到别人使用命令行操作计算机实现自己想要的功能,便会冒出一个念 ...
- 数论 : 模运算法则(poj 1152)
题目:An Easy Problem! 题意:求给出数的最小进制. 思路:暴力WA: discuss中的idea: 给出数ABCD,若存在n 满足 (A* n^3 +B*n^2+C*n^1+D*n^0 ...
- ClickOnce的部署(.appref-ms)在软件限制策略中的解决方案
为了防止百度.360以及一些小厂商在妈妈的电脑里乱安装各种程序,在域中开启了软件限制策略. 今天在用Github的Windows客户端时发现由于软件限制策略无法运行. Github在Windows中采 ...
- windows7 自带l2tp/ipsec VPN客户端连接Cisco ASA
搞了半天,最后发现其实很简单,在ASA默认配置的基础上,把所有crypto ipsec ikev1 transform-set 加上mode transport,然后把tunnel-group Def ...
- 《Linux内核设计与实现》读书笔记(十六)- 页高速缓存和页回写
好久没有更新了... 主要内容: 缓存简介 页高速缓存 页回写 1. 缓存简介 在编程中,缓存是很常见也很有效的一种提高程序性能的机制. linux内核也不例外,为了提高I/O性能,也引入了缓存机制, ...