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 ...
随机推荐
- SQL Server 判定时间是否在某个时间区间内
* FROM sys.objects WHERE name=N'uF_IsRange_Date' AND [type]='FN') DROP FUNCTION uF_IsRange_Date GO S ...
- Nodejs编码转化问题
目前Node.js仅支持hex.utf8.ascii.binary.base64.ucs2几种编码的转换.对于GBK,GB2312等编码,Nodejs自带的toString()方法不支持,因此中文转化 ...
- Android照片墙应用实现,再多的图片也不怕崩溃
本文首发于CSDN博客,转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/9526203 照片墙这种功能现在应该算是挺常见了,在很多应用 ...
- jsp_设置文件编码
jsp有两种方法可以设置文件编码: (1)<%@page language="java" contentType="text/html;charset=utf-8& ...
- android中 EditTex t的 inputType 属性
//文本类型,多为大写.小写和数字符号 android:inputType="none" android:inputType="text" a ...
- jQuery学习总结(一)
jQuery当中独有的对象:jQuery对象: jQuery对象的缩写形式“$”:所以在使用时,我们都是用$来代替jQuery. 所以我们在页面元素选择或执行功能函数的时候可以这么写:$(functi ...
- Programming Assignment 5: Kd-Trees
用2d-tree数据结构实现在2维矩形区域内的高效的range search 和 nearest neighbor search.2d-tree有许多的应用,在天体分类.计算机动画.神经网络加速.数据 ...
- java实验一 20135104刘帅
实验报告 一.实验目的与要求: 实验目的: 1. 使用JDK编译.运行简单的Java程序 2.使用Eclipse 编辑.编译.运行.调试Java程序 实验要求: 1.没有Linux基础的同学建议先学习 ...
- 我们为什麽需要有经验的DBA
我们为什麽需要有经验的DBA 自从我进来园子之后,发觉虽然我们分享了很多质量很好的文章给大家,但是大家不一定能够消化得了这些文章 理解这些文章还是需要有一定环境,有环境你解决了,但是可能还有别的捷径减 ...
- SQLSERVER拯救某个时间点被误删除的数据
SQLSERVER拯救某个时间点被误删除的数据 转载自:http://blog.csdn.net/dba_huangzj/article/details/8491327 要拯救某个时间点被误删除的数据 ...