service是Android四大组件之一,是一个可以在后台执行长时间运行操作而不使用用户界面的组件.。服务可由其他应用组件启动(如activity),服务一旦被启动,将一直在后台运行,即使启动服务的组件(activity)已销毁,也不受影响。此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 (IPC)。 例如,服务可以处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序交互,而所有这一切均可在后台进行。
这种方式是调用startService()方法启动服务,一旦启动,服务即可在后台无限期运行,即使启动服务的组件已被销毁也不受影响,除非手动调用才能停止服务。通常,started的服务执行单一的操作并且不会向调用者返回结果。此种方式会调用service生命周期中的方法有:onCreate()->onStartCommand()->onDestroy()。
通过bindService()方法绑定的Service。bound服务提供了一个客户端/服务器接口,允许组件与服务进行交互、发送请求、获取结果,甚至可以利用进程间通信(IPC)跨进程执行这些操作。绑定服务的生存期和被绑定的应用程序组件一致。 多个组件可以同时与一个服务绑定,不过所有的组件解除绑定后,服务也就会被销毁。
package com.zejian.ipctest.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
/**
1. Created by zejian
2. Time 2016/9/29.
3. Description:service simple demo
*/
public class SimpleService extends Service {
/**
* 绑定服务时才会调用
* 必须要实现的方法
* @param intent
* @return
*/
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* 首次创建服务时,系统将调用此方法来执行一次性设置程序(在调用 onStartCommand() 或 onBind() 之前)。
* 如果服务已在运行,则不会调用此方法。该方法只被调用一次
*/
@Override
public void onCreate() {
System.out.println("onCreate invoke");
super.onCreate();
}
/**
* 每次通过startService()方法启动Service时都会被回调。
* @param intent
* @param flags
* @param startId
* @return
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("onStartCommand invoke");
return super.onStartCommand(intent, flags, startId);
}
/**
* 服务销毁时的回调
*/
@Override
public void onDestroy() {
System.out.println("onDestroy invoke");
super.onDestroy();
}
}
"true" | "false"]
//android:exported:代表是否能被其他应用隐式调用,其默认值是由service中有无intent-filter决定的,如果有intent-filter,默认值为true,否则为false。为false的情况下,即使有intent-filter匹配,也无法打开,即无法被其他应用隐式调用
android:exported=["true" | "false"]
android:icon="drawable resource"
//android:isolatedProcess :设置 true 意味着,服务会在一个特殊的进程下运行,这个进程与系统其他进程分开且没有自己的权限。与其通信的唯一途径是通过服务的API(bind and start)。
android:isolatedProcess=["true" | "false"]
android:label="string resource"
android:name="string"
android:permission="string"
//android:process:是否需要在单独的进程中运行,当设置 android:process=”:remote”时,代表Service在单独的进程中运行。注意“:”很重要,它的意思是指要在当前进程名称前面附加上当前的包名,所以“remote”和”:remote”不是同一个意思,前者的进程名称为:remote,而后者的进程名称为:App-packageName:remote。
android:process="string" >
. . .
AIDL全称Android Interface Definition Language,是Android提供的一种进程间通信机制。
AIDL的使用主要包括三个部分:
在新建的项目中,Java文件夹下鼠标右键 新建AIDL文件,如图所示
给AIDL文件命名后,点击确定,会自动在项目中新建一个aidl文件夹,文件夹内包含新建的aidl文件,如图所示
在Aidl文件中修改或添加方法,然后将整个项目重新构建一下,会自动生成对应AIDL的Java文件,该文件存放在app/build/generate/source/aidl/中,如图所示
在这个文件里包含了Stub;
public static abstract class Stub extends android.os.Binder implements com.xiaoyao.aidl_demo.TestAidl
接下来通过远程服务实现这个Stub
新建service,在service中创建AIDL对应的Stub对象,工onBinder()方法中返回。相关代码如下:
package com.xiaoyao.aidl_demo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
/**
* 对应AIDL服务端
*/
public class TestService extends Service {
public TestService() {
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public IBinder onBind(Intent intent) {
//返回Binder对象,此对象为对应AIDL文件生成的Java文件中的Stub对象
return new TestAidl.Stub() {
@Override
public int getCount(int a, int b) throws RemoteException {
return a+b;
}
};
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
在activity中绑定服务,并开启服务。相关代码如下:
package com.xiaoyao.aidl_demo;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TestAidl mAidl;
private TextView mTv;
private MyServiceConnection mConnection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTv =findViewById(R.id.tv);
initService();
}
private void initService(){
mConnection = new MyServiceConnection();
Intent intent = new Intent(this,TestService.class);
bindService(intent,mConnection,BIND_AUTO_CREATE);
};
class MyServiceConnection implements ServiceConnection{
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//通过binder转化成AIDL对象
mAidl= TestAidl.Stub.asInterface(iBinder);
Log.d("xxx", "onServiceConnected: maidl=" +mAidl);
int count = 0;
try {
//此处用到AIDL接口中的方法,方法的具体实现在service端
count = mAidl.getCount(1,2);
Log.d("xxx", "onServiceConnected: count="+count);
} catch (RemoteException e) {
e.printStackTrace();
}
mTv.setText(Integer.valueOf(count).toString());
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mAidl = null;
}
}
}
ps:不要忘记在androidManifest.xml文件中添加service。
intentService的相关代码如下:
package com.xiaoyao.intentservicedemo;
import android.app.IntentService;
import android.content.Intent;
import android.content.Context;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
/**
* An {@link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
*
* TODO: Customize class - update intent actions, extra parameters and static
* helper methods.
*/
public class MyIntentService extends IntentService {
private static final String TAG = "XXX";
// TODO: Rename actions, choose action names that describe tasks that this
// IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
private static final String ACTION_FOO = "com.xiaoyao.intentservicedemo.action.FOO";
private static final String ACTION_BAZ = "com.xiaoyao.intentservicedemo.action.BAZ";
// TODO: Rename parameters
private static final String EXTRA_PARAM1 = "com.xiaoyao.intentservicedemo.extra.PARAM1";
private static final String EXTRA_PARAM2 = "com.xiaoyao.intentservicedemo.extra.PARAM2";
public MyIntentService() {
super("MyIntentService");
Log.d(TAG, "MyIntentService: ");
}
/**
* Starts this service to perform action Foo with the given parameters. If
* the service is already performing a task this action will be queued.
*
* @see IntentService
*/
// TODO: Customize helper method
public static void startActionFoo(Context context, String param1, String param2) {
Log.d(TAG, "startActionFoo: ");
Intent intent = new Intent(context, MyIntentService.class);
intent.setAction(ACTION_FOO);
intent.putExtra(EXTRA_PARAM1, param1);
intent.putExtra(EXTRA_PARAM2, param2);
context.startService(intent);
}
/**
* Starts this service to perform action Baz with the given parameters. If
* the service is already performing a task this action will be queued.
*
* @see IntentService
*/
// TODO: Customize helper method
public static void startActionBaz(Context context, String param1, String param2) {
Log.d(TAG, "startActionBaz: ");
Intent intent = new Intent(context, MyIntentService.class);
intent.setAction(ACTION_BAZ);
intent.putExtra(EXTRA_PARAM1, param1);
intent.putExtra(EXTRA_PARAM2, param2);
context.startService(intent);
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d(TAG, "onHandleIntent: ");
if (intent != null) {
final String action = intent.getAction();
if (ACTION_FOO.equals(action)) {
final String param1 = intent.getStringExtra(EXTRA_PARAM1);
final String param2 = intent.getStringExtra(EXTRA_PARAM2);
handleActionFoo(param1, param2);
} else if (ACTION_BAZ.equals(action)) {
final String param1 = intent.getStringExtra(EXTRA_PARAM1);
final String param2 = intent.getStringExtra(EXTRA_PARAM2);
handleActionBaz(param1, param2);
}
}
}
/**
* Handle action Foo in the provided background thread with the provided
* parameters.
*/
private void handleActionFoo(String param1, String param2) {
Log.d(TAG, "handleActionFoo: ");
// TODO: Handle action Foo
throw new UnsupportedOperationException("Not yet implemented");
}
/**
* Handle action Baz in the provided background thread with the provided
* parameters.
*/
private void handleActionBaz(String param1, String param2) {
Log.d(TAG, "handleActionBaz: ");
// TODO: Handle action Baz
throw new UnsupportedOperationException("Not yet implemented");
}
}
1. 概念的差别
2. 两者执行任务差异
3.两者使用场景
服务被杀死的情况有以下几种情况: