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: 服务的基本用法的更多相关文章

  1. 从getApplicationContext和getApplication再次梳理Android的Application正确用法

    原文地址http://blog.csdn.net/ly502541243/article/details/52105466 原文地址http://blog.csdn.net/ly502541243/a ...

  2. Android开发--IntentService的用法,你错过了什么

    Android开发--IntentService的用法,你错过了什么 . 本文链接:https://blog.csdn.net/smbroe/article/details/45009721 Inte ...

  3. Android 服务和广播的使用

    Android 服务和广播的使用 服务的使用 创建服务类 创建一个java文件,取名 mService.java,继承Service. public class mService extends Se ...

  4. android的logcat详细用法

    Android日志系统提供了记录和查看系统调试信息的功能.日志都是从各种软件和一些系统的缓冲区中记录下来的,缓冲区可以通过 logcat 命 令来查看和使用. 使用logcat命令 你可以用 logc ...

  5. 怎么通过activity里面的一个按钮跳转到另一个fragment(android FragmentTransaction.replace的用法介绍)

    即:android FragmentTransaction.replace的用法介绍 Fragment的生命周期和它的宿主Activity密切相关,几乎和宿主Activity的生命周期一致,他们之间最 ...

  6. Android 服务类Service 的详细学习

    http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建   目录(?)[+] 什么是服务 服务有 ...

  7. Android开发中Bundle用法包裹数据(转)

    Android开发中Bundle用法包裹数据 Bundle的经典用法,包裹数据放入Intent中,目的在于传输数据. SDK 里是这样描述: A mapping from String values ...

  8. 【转】Android各种Adapter的用法

    转自:http://my.oschina.net/u/658933/blog/372151 Android各种Adapter的用法 发表于5个月前(2015-01-27 10:56)   阅读(143 ...

  9. Android 服务端开发之开发环境配置

    Android 服务端开发之开发环境配置 这里是在Eclipse的基础上安装PhpEclipse插件方法,PHPEclipse是Eclipse的 一个用于开发PHP的插件.当然也可以采用Java开发a ...

随机推荐

  1. [转] 关于linux下通过shell命令(自动)修改用户密码

    关于linux下通过shell命令(自动)修改用户密码 2012-04-23 18:47:39 分类: 原文地址:关于linux下(自动)修改用户密码 作者:ubuntuer 本文章总结了如何手动.自 ...

  2. mysql 大小写 整理

    mysql字段的值默认不区分大小写,如果有主键的表,主键列就不能插入重复的值(大小写不同) 实验 默认方式创建 CREATE TABLE `t1` ( `ID` varchar(40) CHARACT ...

  3. markdown编辑器实现笔记

    1.js代码放在head和body的区别 <html> <head> <script src="https://cdnjs.cloudflare.com/aja ...

  4. 应该了解的Python模块

    Python很优雅.使用以下模块有助于保持你的代码整洁.易于维护.欢迎补充. Docopt.忘了optparse和argparse吧,使用docstring来构建优雅的.高可读性.复杂(如果你有这个需 ...

  5. Github两步认证

    获取密钥:ssh-keygen -t rsa  切换到公钥所在路径:cd .ssh 查看该路径下的所有文件:ls 查看公钥:cat id_rsa.pub 获取密钥之后,去https://github. ...

  6. freeCodeCamp:Find the Longest Word in a String

    找到提供的句子中最长的单词,并计算它的长度. 函数的返回值应该是一个数字. /* 先把字符串 str 转为数组 myarr 将数组myarr中的每个元素长度转换成一个新的数组newarr 将这个数组按 ...

  7. 【使用git】初识git

    0. 版本控制 版本控制是一种记录若干文件内容变化,以便将来查阅特定版本修改情况的系统(vcs). svn等是集中式版本控制,即服务器在单一机器上,每次checkout变化的文件,若机器故障,则有可能 ...

  8. 用SQL语句,删除掉重复项只保留一条

    用SQL语句,删除掉重复项只保留一条 在几千条记录里,存在着些相同的记录,如何能用SQL语句,删除掉重复的呢1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 select ...

  9. MySQL MHA配置

    MySQL环境: master:192.168.202.129:3306 slave:192.168.202.129:3307,192.168.202.129:3307,192.168.202.130 ...

  10. .NET调用window串口读取电子秤的数据

    Private serialPort As SerialPort  '定义 Public Function CreateSerialPort() As String        Dim strWei ...