-
前言
继上两篇简单介绍了Activity之后,我们开始学习同样是Android四大应用程序组件之一的Service。
本文要点:
1.Service概述
2.Service生命周期
3.创建并启动Service
-
Service概述
Service和Activity有些类似,都继承自Context,但Service有以下特点:
(1)Service没有界面,在后台长时间运行,即使用户已经切换到其他的应用程序;
(2)Service不能自行启动,需要借助Activity,其他Service,或者其他Context对象;
(3)Service有两种模式:Started和Bound。启动方式分别为调用Context.startService()和Context.bindService();
(4)我们创建的Service也可以被其他应用访问,除非将Service声明为Private;
(5)Service和当前运行的应用是同一个进程,它会阻塞当前应用的其他操作。如果不希望Service阻塞其他操作,可以在调用时创建一个线程去启动Service。
-
Service生命周期
和Activity一样,这里也有一张图:
针对上图中几个重要方法的说明:
(1)onStartCommand(),当使用startService()启动时,系统会调用该方法。程序中实现(重写)该方法后,需要显示的调用stopService()。如果Service仅仅支持Bound模式,则不需要实现该方法。
(2)onBind(),通过bindService()启动时,需要实现该方法。如果不允许绑定这里可以返回null。
(3)onCreated(),在服务第一次创建时调用。在onStartCommand()和onBind()之前。
(4)onDestroy(),调用stopService()或者unbindService()时,系统会调用该方法,我们这一在这里释放资源。
两种不同形式(Started和Bound)下,Service的生命周期是有差别的:
1.Started模式:
Context.startService() -> onCreate() -> onStartCommand() -> onStart() -> Running;
Context.stopService() -> onDestroy() -> Stoped。
2.Bound模式:
Context.bindService() -> onCreate() -> onBind()-> Running;
Context.unbindService() -> onDestroy() -> Stoped。
注:本文下面给出的例子,能够很直观的看出这个调用过程。
-
创建Service
1.打开Eclipse创建一个project,命名为HelloService;
2.新建类MyService,使其继承Service;
package com.wZhang.helloservice.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.i("MyService", "onBind()");
return null;
}
}
3.在AndroidManifest.xml中声明MyService:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.wZhang.helloservice.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.wZhang.helloservice.service.MyService" >
</service>
</application>
Service和Activity是在同一级配置的。这样,我们就创建了一个service。接下来我们尝试使用不同方式启动这个Service。
-
启动Service
1.我们在Activity中添加几个Button,并为其绑定click事件。
main.xml代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".MainActivity" >
<Button
android:id="@+id/btnStartService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:onClick="startService"
android:text="Start"
android:textSize="20sp" />
<Button
android:id="@+id/btnStopService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:onClick="stopService"
android:text="Stop"
android:textSize="20sp" />
<Button android:id="@+id/btnBindService"
android:text="Bind"
android:onClick="bindService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_marginTop="10dp"/>
<Button android:id="@+id/btnUnbindService"
android:text="Unbind"
android:onClick="unbindService"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_marginTop="10dp"/>
</LinearLayout>
MainActivity.java代码:
package com.wZhang.helloservice;
import com.wZhang.helloservice.service.MyService;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
//Start方式启动服务
public void startService(View view) {
//TODO:Start Service
}
//Start方式停止服务
public void stopService(View view){
//TODO:Start Service
}
//Bind方式启动服务
public void bindService(View view) {
//TODO:Bind Service
}
//unbind服务
public void unbindService(View view){
//TODO:Unbind Service
}
}
2.修改MyService类,重写(override)相关方法,并增加log:
package com.wZhang.helloservice.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.i("MyService", "onCreate()");
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.i("MyService", "onBind()");
return null;
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
Log.i("MyService", "onStart()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.i("MyService", "onStartCommand()");
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
Log.i("MyService", "onUnbind()");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i("MyService", "onDestroy()");
}
}
3.实现startService,stopService,bindService,unbindService方法:
//Define ServiceConnection
private ServiceConnection conn =new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
// TODO Auto-generated method stub
Log.i("MyService", "连接成功!");
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
Log.i("MyService", "断开连接!");
}
};
//Start方式启动服务
public void startService(View view) {
Intent intent = new Intent(this,MyService.class);
startService(intent);
}
//Start方式停止服务
public void stopService(View view){
Intent intent = new Intent(this,MyService.class);
stopService(intent);
}
//Bind方式启动服务
public void bindService(View view) {
Intent intent = new Intent(this,MyService.class);
bindService(intent,conn,Service.BIND_AUTO_CREATE);
}
//Unbind服务
public void unbindService(View view){
unbindService(conn);
}
4.运行HelloService,界面如下:
(1)点击Start按钮,Logcat信息:
(2)点击stop按钮:
(3)点击Bind按钮:
(4)点击Unbind按钮:
至此,我们发现:Started和Bound方式都可以启动、停止Service;同时也能直观的看到两种方式下Service生命周期中的方法调用过程。