启动式服务(Started Service)
- 应用组件通过 <code>startService()</code> 方法来启动服务,一旦启动,服务会在后台运行,即使启动该服务的组件被销毁;
- 启动式服务不会向启动它的组件返回任何结果,也就是说,启动式服务不能与组件进行交互;
- 启动式服务一旦被启动,就会一直运行,直到它使用 <code>stopSelf()</code> 方法停止服务或在其他应用组件中使用 <code>stopService()</code> 方法停止服务。
创建启动式服务
服务端
- 自定义一个类,继承自 Service 类,重写如下几个方法:
- onBind(): 绑定式服务会调用此方法,启动式服务不会调用此方法,但必须重写此方法;
-
onStartCommand(): 当其他应用组件每次启动服务时会调用此方法,该方法需要传入三个参数:
- Intent intent:启动服务的 Intent 对象;
- int flags:启动服务时的额外信息;
- int startId:每次启动服务时的 Id;
该方法的返回值为 int 类型,其值有:- START_NOT_STICKY:非粘性标识,系统内存不足时,系统将服务 kill 掉之后不会再重新创建一个新的服务进程;
- START_STICKY:粘性标识,系统内存不足时,系统会将服务 kill 掉,之后马上重新创建一个新的服务进程,但是传入的 Intent 为 null;
- START_REDELIVER_INTENT:带数据的粘性标识,系统内存不足时,系统将服务 kill 掉之后会马上重新创建一个新的服务进程,传入的 Intent 为上一次传入的 Intent;
- START_STICKY_COMPATIBILITY:START_STICKY 的兼容版本,但不保证一定重新创建一个新的服务进程;
- onCreate(): 第一次启动服务时会调用此方法,当服务已经启动但并未停止时,再次启动服务不会调用此方法;
- onDestroy(): 当服务不再使用或者被销毁时会调用此方法,应当在此方法内回收那些不再使用的资源,比如线程、监听器等;
- 在 AndroidManifest.xml 中注册。
客户端
- 使用 <code>Context.startService(Intent intent)</code> 方法来启动服务,该方法需要传入一个 Intent 对象,用来指定当前所在的类及需要启动的服务的类名;
- 使用 <code>Context.stopService(Intent intent)</code> 方法来停止服务,该方法需要传入一个 Intent 对象,用来指定当前组件的类名及需要启动的服务的类名(或在服务端服务调用 <code>stopSelf()</code> 方法来自己停止服务);
启动式服务的简单使用
下面举个例子简单演示一下。
服务端
1. 自定义一个类,继承 Service 类,并重写相应的方法:
/**
* Created by Monkey.C on 2016/5/13.
*/
public class MyService extends Service {
private final String TAG = "MyService";
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind");
return null;
}
// 此方法在服务第一次创建时调用
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
}
// 此方法在每次启动服务时调用
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand --> " + startId);
return START_FLAG_REDELIVERY;
}
// 此方法在服务停止时调用,应当此方法内回收那些不再使用的资源
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
}
2. 在 AndroidManifest.xml 中注册,AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.monkeychan.servicetest01">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyService"/>
</application>
</manifest>
客户端
1. 使用一个 Activity 来启动服务和停止服务,主界面布局文件,activity_main:
<?xml version="1.0" encoding="utf-8"?>
<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"
android:padding="16sp"
tools:context=".MainActivity">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="startService"
android:text="启动服务" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="stopService"
android:text="停止服务" />
</LinearLayout>
2. MainActivity.java:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// 此方法用来启动服务
public void startService(View view) {
Intent intent = new Intent(this, MyService.class);
startService(intent);
}
// 此方法用来停止服务
public void stopService(View view) {
Intent intent = new Intent(this, MyService.class);
stopService(intent);
}
}
效果演示:
点击 <code>启动服务</code> 按钮,此时 logcat 日志如下:
多次点击 <code>启动服务</code> 按钮,此时 logcat 日志如下:
可以看到每次启动服务的 Id 都不相同。
点击 <code>停止服务</code> 按钮,此时 logcat 日志如下:
启动式服务的简单使用就是这样。
参考资料: