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()方法可以得到执行了。

时间: 2024-10-28 16:41:01

android: 服务的基本用法的相关文章

【android】Socket简单用法

原文地址:http://www.cnblogs.com/harrisonpc/archive/2011/03/31/2001565.html Socket通常也称做”套接字“,用于描述IP地址和端口,废话不多说,它就是网络通信过程中端点的抽象表示.值得一提的是,Java在包java.net中提供了两个类Socket和ServerSocket,分别用来表示双向连接的客户端和服务端.这是两个封装得非常好的类,使用起来很方便! 下面将首先创建一个SocketServer的类作为服务端如下,该服务端实现

Android——服务

服务默默的在后台工作着,执行着不需要和用户交互的工作. 服务依赖于应用程序进程而存活 作为四大组件之一,服务具备共同的特点——需要在AndroidManifest中注册 Android多线程编程 需要注意的是——一定不要在子线程中进行UI操作,否则会阻塞主线程出现异常 1 /** 主要的逻辑是在这里完成,但是考虑到:服务默认是在主线程执行的,如果在这里进行比较费时的操作<br/> 2 * 就容易出现ANR(Application Not Responding).<br/> 3 *

android服务unbind之后再想绑定问题

突然遇到个问题, 问题描述: 我按照顺序来绑定一个服务:start->bind 最后在退出activity的时候unbind一下, 现在我有这样的业务需求,就是当我再次进入该activity时需要再次bind, 我发现再调用bind方法并不能绑定服务(不知道google工程师为啥要设计成这样.) 写了一段测试代码验证一下: Service: package org.load.testservice; import android.app.Service; import android.conte

Android中this的用法

关于Android中this的用法解释 问题由来 由于很多同学在学习Android时候没有对Java有很深的了解,很多人都会对代码中各种各样的this产生疑惑. 以<第一行代码Android>P37页,P43页代码为例: protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.first_layout); Button but

erlang-百度云推送Android服务端功能实现-erlang

百度云推送官方地址http://developer.baidu.com/wiki/index.php?title=docs/cplat/push 简单的介绍下原理: 百度云推送支持IOS和Android的云推送.Android支持的还不错,但是IOS一般很难调通.百度云对于IOS的推送来说,他只是做了一个中间的代理,为用户提供接口,优点是使用百度云推送,Android和IOS可以统一管理:缺点是:调通不容易,用户的IOS证书需要上传验证,会直接暴露给第三方,并且IOS的apns支持用户自己构建p

android 服务与多线程

android服务是执行在UI主线程的.一下是代码demo: package com.example.testservice; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCr

【Android】Android背景选择器selector用法汇总

一.创建xml文件,位置:drawable/xxx.xml,同目录下记得要放相关图片 <?xml version="1.0" encoding="utf-8" ?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 默认时的背景图片--> <item android:drawable="@draw

关于Android 中 raw的用法以及与assets 的的区别和共同点

一.raw与assets的区别及共同点 (1) res/raw和assets的相同点 两个目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制. (2) res/raw和assets的不同点: 1.res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.raw.filename: assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类. 2.res/raw不可以有目录结构,而assets则可以有目录结构,也就是a

Android 服务类Service 的详细学习

上一篇说到了通知栏Notification,提起通知栏,不得让人想到Service以及BroadcastReceive,作为android的4大组建的2个重要成员,我们没少和它们打交道.它们可以在无形中使我们的软件和网络.数据库.系统等进行交互,之后通过UI(Notification就是一种展示方式)把结果展现在我们面前.可以说,他们是android生命体系里面的神经系统,通过反射条件让身体展现不同的状态.在整个系统中,广播接收器充当着是传输者和监听者的角色,它把系统的一点点变化都反馈上去,之后