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. CentOS7安装mysql5.7.11

    开始安装 yum update yum install wget wget http://repo.mysql.com/mysql57-community-release-el7-7.noarch.r ...

  2. mysql 大小写 整理

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

  3. 浏览器css bug及bug解决方法

    Bugs及解决方案列表(以下实例默认运行环境都为Standard mode): 如何在IE6及更早浏览器中定义小高度的容器? 方法: #test{overflow:hidden;height:1px; ...

  4. 自定义安装php开发环境(1)--apache和php整合

    第一步:安装apache 第二步:下载php核心包php-5.3.3-Win32-VC6-x86.zip.并放入开发环境文件夹C:/phpenv/文件夹下 第三步: 将apache 和php 整合 也 ...

  5. vim不用鼠标复制粘贴

    第一种方法(只能复制行): 在当前行3yy(表示复制3行,多行同理),然后鼠标移到需要粘贴的位置,按p,即可粘贴 第二种方法(无限制): 按v进入visual模式,移动光标(推荐使用hjkl,用熟后比 ...

  6. ssh: connect to host gihub.com port 22: Connection timed out

    方案1(本人使用此方案,问题得已解决): 可能是ssh-server未安装或者未启动.我的ubuntu 12.04 默认只安装了openssh-client,并没有安装server. 运行 ps -e ...

  7. .net委托(转载)

    一.什么是委托? 委托就是定义一个 对于方法的引用,类似于c++中的函数指针.委托是用来将方法作为参数 传递进入其它方法的, 委托的格式? 修饰符1 delegate  修饰符2  委托类型名(变量n ...

  8. Android开源框架——Picasso

    开篇——介绍Picasso (Picasso是什么?)Picasso:A Powerfull Image Downloading and Caching Library for Android,即An ...

  9. ASP通过代码绑定Gridview控件

    using System.Configuration;using System.Data.OleDb;using System.Data; public partial class datafilm ...

  10. git 使用笔记

    git操作: git checkout 分支名称 // 切换分支git branch -a // 查看分支信息和当前分支 git pull // 将服务器所有代码下载到本地git merge orig ...