首先,给大家看一张生命周期图:
写过一些android程序,但是android中的Service的组件却不曾用过,因此,对它也不甚了解,所以,今天写个小例子来学习如何使用Service。这其实也是我学习新东西的一个方法,对于陌生的东西,看书只是理论只是的了解,但是实际的情况如何,还是需要写些程序来测试,那样的理解更深刻。
测试目的:了解Service的生命周期,以及在startService和bindService时,Service如何响应。
程序界面如下:
1、编写Android Service需要基础Service类,并实现其中的onBind方法
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class TestService extends Service {
@Override
public IBinder onBind(Intent intent) {
System.out.println("========onCreate========");
return null;
}
/**
* 初始化服务对象
*/
@Override
public void onCreate() {
System.out.println("========onCreate========");
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
System.out.println("========onStart========");
super.onStart(intent, startId);
}
/**
* 销毁服务对象时调用这个方法
*/
@Override
public void onDestroy() {
System.out.println("========onDestroy========");
super.onDestroy();
}
/**
* 开启一个服务
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("========onStartCommand========");
return super.onStartCommand(intent, flags, startId);
}
}
2、在AndroidManifest.xml文件中声明Service组件:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.fly.testservice"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.fly.trvice.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>
<span style="color:#ff0000;"><service android:name="com.fly.testservice.TestService"></service></span>
</application>
</manifest>
具体测试代码如下:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void start(View view) {
intent = new Intent(this, TestService.class);
// 开启服务,可以长期运行在后台
startService(intent);
}
public void stop(View view) {
//停止服务
//intent 开启服务端的时候使用的意图对象
stopService(intent);
}
}
xml文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开启服务"
android:onClick="start" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止服务"
android:onClick="stop" />
</LinearLayout>
4、日志输出
启动服务的时候
11-18 16:10:20.181: I/System.out(16200): ========onCreate========
11-18 16:10:20.181: I/System.out(16200): ========onStartCommand========
再次启动的时候
11-18 16:10:20.181: I/System.out(16200): ========onStartCommand========
可以看出,在第一次点击时,因为Service还未创建,所以调用了onCreate方法,紧接着调用了onStartCommand和onStart方法。当再次点击启动服务时,仍然调用了onStartCommand和onStart方法,所以,在Service中做任务处理时需要注意这点,因为一个Service可以被重复启动。
这里说一下,平常使用多的是startService方法,可以把一些耗时的任务放到后台去处理,当处理完成后,可以通过广播来通知前台。
而onBind方法更多的是结合AIDL来使用,这样一个应用可以通过绑定服务获得的IBinder来拿到后台的接口,进而调用AIDL中定义的方法,进行数据交换等。
停止服务
11-18 16:11:26.851: I/System.out(16200): ========onDestroy========
总结:
context.startService() -> onCreate() -> onStartCommand() -> Service running -> context.stopService() -> onDestroy() -> Service stop
所以调用startService的生命周期大致为:
onCreate(只在创建的时候调用一次直到被摧毁) --> onStartCommand (服务开启后,可多次调用) -->
服务中的onStartCommand(Intent intent, int flags, int startId)方法会返回一个唯一的整数标识符来识别启动请求,启动请求可以是START_STICKY、START_STICKY_COMPATIBILITY、START_NOT_STICKY、START_REDELIVER_INTENT等,标志位可以是START_FLAG_REDELIVERY、START_FLAG_RETRY。
通过这种方式,服务并不会随着绑定组建的摧毁而摧毁,而是服务自我摧毁。(所以这种方式适用于文件下载,上传等请求自行运行的场景)。