android: 服务的基本用法
9.3 服务的基本用法
了解了 Android 多线程编程的技术之后,下面就让我们进入到本章的正题,开始对服务 的相关内容进行学习。作为 Android 四大组件之一,服务也少不了有很多非常重要的知识点, 那我们自然要从最基本的用法开始学习了。
9.3.1 定义一个服务
首先看一下如何在项目中定义一个服务。新建一个 ServiceTest 项目,然后在这个项目中 新增一个名为 MyService 的类,并让它继承自 Service,完成后的代码如下所示:
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
目前 MyService 中可以算是空空如也,但有一个 onBind()方法特别醒目。这个方法是 Service 中唯一的一个抽象方法,所以必须要在子类里实现。我们会在后面的小节中使用到 onBind()方法,目前可以暂时将它忽略掉。
既然是定义一个服务,自然应该在服务中去处理一些事情了,那处理事情的逻辑应该写 在哪里呢?这时就可以重写 Service 中的另外一些方法了,如下所示:
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
可以看到,这里我们又重写了 onCreate()、onStartCommand()和 onDestroy()这三个方法, 它们是每个服务中最常用到的三个方法了。其中
onCreate()方法会在服务创建的时候调用,
onStartCommand()方法会在每次服务启动的时候调用,onDestroy()方法会在服务销毁的时候 调用。
通常情况下,如果我们希望服务一旦启动就立刻去执行某个动作,就可以将逻辑写在 onStartCommand()方法里。而当服务销毁时,我们又应该在 onDestroy()方法中去回收那些不
再使用的资源。
另外需要注意,每一个服务都需要在 AndroidManifest.xml 文件中进行注册才能生效,不知 道你有没有发现,这是 Android 四大组件共有的特点。于是我们还应该修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=".MyService" >
</service>
</application>
</manifest>
这样的话,就已经将一个服务完全定义好了。
9.3.2 启动和停止服务
定义好了服务之后,接下来就应该考虑如何去启动以及停止这个服务。启动和停止的方
法当然你也不会陌生,主要是借助 Intent 来实现的,下面就让我们在 ServiceTest 项目中尝试 去启动以及停止 MyService 这个服务。
首先修改 activity_main.xml 中的代码,如下所示:
<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_service"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:text="Start Service" />
<Button
android:id="@+id/stop_service"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:text="Stop
Service" />
</LinearLayout>
这里我们在布局文件中加入了两个按钮,分别是用于启动服务和停止服务的。 然后修改 MainActivity 中的代码,如下所示:
public class MainActivity extends Activity implements
OnClickListener {
private Button startService;
private Button stopService;
@Override
protected void
onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService = (Button) findViewById(R.id.start_service);
stopService = (Button) findViewById(R.id.stop_service);
startService.setOnClickListener(this);
stopService.setOnClickListener(this);
}
@Override
public void onClick(View
v) {
switch (v.getId()) {
case R.id.start_service:
Intent startIntent = new Intent(this, MyService.class);
startService(startIntent); // 启动服务
break;
case R.id.stop_service:
Intent stopIntent = new Intent(this, MyService.class);
stopService(stopIntent); // 停止服务
break;
default:
break;
}
}
}
可以看到,这里在 onCreate()方法中分别获取到了 Start Service 按钮和 Stop Service 按钮 的实例,并给它们注册了点击事件。然后在 Start Service 按钮的点击事件里,我们构建出了 一个 Intent 对象,并调用 startService()方法来启动 MyService 这个服务。在 Stop Serivce 按钮 的点击事件里,我们同样构建出了一个 Intent 对象,并调用 stopService()方法来停止 MyService
这个服务。startService()和 stopService()方法都是定义在 Context 类中的,所以我们在活动里 可以直接调用这两个方法。注意,这里完全是由活动来决定服务何时停止的,如果没有点击 Stop Service 按钮,服务就会一直处于运行状态。那服务有没有什么办法让自已停止下来呢? 当然可以,只需要在 MyService 的任何一个位置调用 stopSelf()方法就能让这个服务停止下 来了。
那么接下来又有一个问题需要思考了,我们如何才能证实服务已经成功启动或者停止了
呢?最简单的方法就是在 MyService 的几个方法中加入打印日志,如下所示:
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
Log.d("MyService", "onCreate executed");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d("MyService", "onStartCommand
executed");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyService", "onDestroy executed");
}
}
现在可以运行一下程序来进行测试了,程序的主界面如图 9.5 所示。

图 9.5
点击一下 Start Service 按钮,观察 LogCat 中的打印日志如图 9.6
所示。

图 9.6
MyService 中的 onCreate()和 onStartCommand()方法都执行了,说明这个服务确实已经启
动成功了,并且你还可以在正在运行的服务列表中找到它,如图 9.7
所示。

图 9.7
然后再点击一下 Stop Service 按钮,观察 LogCat 中的打印日志如图 9.8 所示。

图 9.8
由此证明,MyService 确实已经成功停止下来了。
话说回来,虽然我们已经学会了启动服务以及停止服务的方法,不知道你心里现在有没有一个疑惑,那就是 onCreate()方法和 onStartCommand()到底有什么区别呢?因为刚刚点击
Start Service 按钮后两个方法都执行了。
其实 onCreate()方法是在服务第一次创建的时候调用的,而 onStartCommand()方法则在 每次启动服务的时候都会调用,由于刚才我们是第一次点击 Start Service 按钮,服务此时还 未创建过,所以两个方法都会执行,之后如果你再连续多点击几次 Start Service 按钮,你就 会发现只有 onStartCommand()方法可以得到执行了。
android: 服务的基本用法的更多相关文章
- 从getApplicationContext和getApplication再次梳理Android的Application正确用法
原文地址http://blog.csdn.net/ly502541243/article/details/52105466 原文地址http://blog.csdn.net/ly502541243/a ...
- Android开发--IntentService的用法,你错过了什么
Android开发--IntentService的用法,你错过了什么 . 本文链接:https://blog.csdn.net/smbroe/article/details/45009721 Inte ...
- Android 服务和广播的使用
Android 服务和广播的使用 服务的使用 创建服务类 创建一个java文件,取名 mService.java,继承Service. public class mService extends Se ...
- android的logcat详细用法
Android日志系统提供了记录和查看系统调试信息的功能.日志都是从各种软件和一些系统的缓冲区中记录下来的,缓冲区可以通过 logcat 命 令来查看和使用. 使用logcat命令 你可以用 logc ...
- 怎么通过activity里面的一个按钮跳转到另一个fragment(android FragmentTransaction.replace的用法介绍)
即:android FragmentTransaction.replace的用法介绍 Fragment的生命周期和它的宿主Activity密切相关,几乎和宿主Activity的生命周期一致,他们之间最 ...
- Android 服务类Service 的详细学习
http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建 目录(?)[+] 什么是服务 服务有 ...
- Android开发中Bundle用法包裹数据(转)
Android开发中Bundle用法包裹数据 Bundle的经典用法,包裹数据放入Intent中,目的在于传输数据. SDK 里是这样描述: A mapping from String values ...
- 【转】Android各种Adapter的用法
转自:http://my.oschina.net/u/658933/blog/372151 Android各种Adapter的用法 发表于5个月前(2015-01-27 10:56) 阅读(143 ...
- Android 服务端开发之开发环境配置
Android 服务端开发之开发环境配置 这里是在Eclipse的基础上安装PhpEclipse插件方法,PHPEclipse是Eclipse的 一个用于开发PHP的插件.当然也可以采用Java开发a ...
随机推荐
- Codeforces 714C. Sonya and Queries Tire树
C. Sonya and Queries time limit per test:1 second memory limit per test: 256 megabytes input:standar ...
- NFS配置
一,配置nfs服务端 nfs服务端IP:192.168.1.10 1,安装nfs [root@localhost ~]# yum install -y nfs-utils Loaded plugins ...
- Android音频系统之AudioFlinger(四)
http://blog.csdn.net/xuesen_lin/article/details/8805096 1.1.1 AudioMixer 每一个MixerThread都有一个唯一对应的Audi ...
- Problem 2136 取糖果---FUOJ (线段树+维护)
http://acm.fzu.edu.cn/problem.php?pid=2136 题目大意: 给你n个袋子每个袋子里都装有糖果,然后呢你可以每次抽取一个连续的一个区间的袋子,然后带走里面最多糖果数 ...
- 基本套接字编程(4) -- poll篇
1. poll技术 poll函数起源于SVR3,最初局限于流设备.SVR4取消了这种限制,允许poll工作在任何描述符上.poll提供的功能与select类似,不过在处理流设备时,它能够提供额外的信息 ...
- js全局变量和局部变量
<script> var i = 'yuanjianhang'; function myloveName() { alert(i); var i = 'guanxi'; } myloveN ...
- 在centos上编译安装mariadb数据库
一.安装前提(准备数据文件.安装其他依赖的软件) 1.准备数据存放的目录 [root@localhost ~]# fdisk /dev/sdb (fdisk /dev/sdb 创建一个逻辑分区/de ...
- web兼容性测试
1.前端的兼容性问题 a. 客户端操作系统 -pc电脑 -windows -mac os -Linux -平板 -手机 -智能终端 -响应式布局 借助于css3 b.客户端浏览器 IE firefo ...
- 修改默认MYSQL数据库data存放位置
随着业务量的增长,mysql默认安装所在分区大小出现瓶颈,通常需要将datadir换到较大的分区 示例原目录:/usr/local/mysql/data/示例新目录:/data/mysqldata/ ...
- java抓取网页数据,登录之后抓取数据。
最近做了一个从网络上抓取数据的一个小程序.主要关于信贷方面,收集的一些黑名单网站,从该网站上抓取到自己系统中. 也找了一些资料,觉得没有一个很好的,全面的例子.因此在这里做个笔记提醒自己. 首先需要一 ...