Service是android 系统中的四大组件之一(Activity、Service、BroadcastReceiver、ContentProvider),它跟Activity的级别差不多,但不能自己运行只能后台运行,并且可以和其他组件进行交互。
服务一般分为两种:
1:本地服务, Local Service 用于应用程序内部。在外部可以调用Context.startService()启动,调用Context.stopService()结束。在内部可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。无论调用了多少次startService(),都只需调用一次stopService()来停止。
2:远程服务, Remote Service 用于android系统内部的应用程序之间。可以定义接口并把接口暴露出来,以便其他应用进行操作。客户端建立到服务对象的连接,并通过那个连接来调用服务。调用Context.bindService()方法建立连接,并启动,以调用 Context.unbindService()关闭连接。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。提供给可被其他应用复用,比如定义一个天气预报服务,提供与其他应用调用即可。
那么先来看Service的生命周期吧:如图:
两种方式启动的Demo:
AndroidManifest.xml:
activity_main.xml:
android:id="@+id/bindservice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="bindservice" />
android:id="@+id/unbindservice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="unbindservice" />
android:id="@+id/startservice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="startservice" />
android:id="@+id/stopservice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="stopservice" />
android:id="@+id/shutup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="shutup" />
MainActivity.java:
public class MainActivity extends Activity {
private Button bindService, unBindService, startService, stopService, shutUp;
ServiceConnection conn = new ServiceConnection() {
//当绑定不成功时调用
@Override
public void onServiceDisconnected(ComponentName name) {
}
//当绑定成功时调用,这个调用都是系统回调的。
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.v("TAG", "...ServiceConnection...");
MyBind bind = (MyBind) service;
ServiceByBind st = bind.getService(); // ....得到service对象,可以使用serivce中的相关方法
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindService = (Button) findViewById(R.id.bindservice);
unBindService = (Button) findViewById(R.id.unbindservice);
startService = (Button) findViewById(R.id.startservice);
stopService = (Button) findViewById(R.id.stopservice);
shutUp = (Button) findViewById(R.id.shutup);
//bindService启动service
bindService.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(getApplicationContext(), ServiceByBind.class);
bindService(intent, conn, BIND_AUTO_CREATE);
}
});
//停止bindService方式启动的service
startService.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this,
ServiceByStart.class);
startService(intent);
}
});
//startService启动service
unBindService.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
ActivityManager am = (ActivityManager)getApplicationContext().getSystemService(ACTIVITY_SERVICE);
List
for(RunningServiceInfo info : list){
if(info.service.getClassName().equals("com.example.test_service.ServiceByBind")){
unbindService(conn);
}
}
//用bindService启动的方式必须要判断当前service是否已开启,否则解除绑定会报错。
}
});
//停止startService方式启动service
stopService.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
stopService(new Intent(MainActivity.this, ServiceByStart.class));
}
});
//销毁Activity,这里只有一个Activity,所以就是退出应用了。
shutUp.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
finish();
}
});
}
}
bindService启动方式:
ServiceByBind.java:
package com.example.test_service;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class ServiceByBind extends Service {
private MyBind bind = new MyBind();
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.v("TAG", "onBind");
return bind; //在ServiceConnection的方法onServiceConnected(ComponentName name, IBinder service)中
//的参数service就是在这里返回的
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
Log.v("TAG", "onCreate");
super.onCreate();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.v("TAG", "onDestroy");
// stopSelf();
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.v("TAG", "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
Log.v("TAG", "onUnbind");
// stopSelf();
return super.onUnbind(intent);
}
//通过此内部类返回service对象,也就是通常说的向外部提供接口。
public class MyBind extends Binder {
ServiceByBind getService() {
return ServiceByBind.this;
}
}
}
详细说明:
启动:bindService(Intent,ServiceConnection,int),因为有必须要有ServiceConnection这个参数,所以,我们便创建一个:
ServiceConnection conn = new ServiceConnection() {
//当绑定不成功时调用
@Override
public void onServiceDisconnected(ComponentName name) {
}
//当绑定成功时调用,这个调用都是系统回调的。
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.v("TAG", "...ServiceConnection...");
MyBind bind = (MyBind) service; //向上转型
ServiceByBind st = bind.getService(); // ....得到service对象,可以使用serivce中的相关方法
}
};
看看上面的第二个方法,因为参数中有IBinder这东西,这是一个接口,而Binder实现了这个接口,所以我们的service中必须要提供Binder的子类对象,
要不然这个回调的方法就不走了,所以我们在service中创建继承Binder的内部类,然后把这个内部类的对象返回。onBind()干的这事。
private MyBind bind = new MyBind();
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.v("TAG", "onBind");
return bind; //在ServiceConnection的方法onServiceConnected(ComponentName name, IBinder service)中
//的参数service就是在这里返回的
}
这样在上面Activity 中的onServiceConnected()中我们就得到了service对象,在里面就可以用service中的东西了。
用这个绑定service的方式,我们可以在两个应用之间互相访问,AILD进程间的通信也是基于这样的原理,只不过多了一个aidl文件和一些其他的方法而已。最后,要注意一点。
bindService(intent, conn, BIND_AUTO_CREATE);
第二个参数别忘了。
以上只是个人理解,如果有偏差,欢迎指出,互相交流,我也是个新手~~~~