2)和Activity交互的本地服务
刚刚我们介绍的Service是不需要与Activity进行交互的,现在我们再来看看与Activity交互的本地服务。首先,我们新建一个BindLocalServide类继承自Serivce,代码如下:
// import略 public class BindLocalServideextends Service {
private static final String TAG = "localservice"; private MyBinder myBinder = new MyBinder();
@Override public IBinder onBind(Intent intent) { return myBinder; } @Override public void onCreate() { super.onCreate(); } @Override public void onDestroy() { super.onDestroy(); } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); }
public class MyBinder extends Binder{ public LocalService getService(){ return LocalService.this; } } } |
然后,我们新建一个BindServiceActivity类继承自Actvity,代码如下:
// import略 public class BindServiceActivity extends Activity{
private Button startBtn,stopBtn; private boolean flag;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.localservice); startBtn = (Button)findViewById(R.id.start_button); stopBtn = (Button)findViewById(R.id.stop_button); startBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(BindServiceActivity.this,LocalService.class); bindService(intent, conn, Context.BIND_AUTO_CREATE); } }); stopBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(flag == true){ unbindService(conn); flag = false; } } }); } private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) {
}
@Override public void onServiceConnected(ComponentName name, IBinder service) { MyBinder binder = (MyBinder)service; LocalService bindService = binder.getService(); bindService.MyMethod(); flag = true; } }; } |
在这里,也是使用之前使用过的localservice.xml布局文件,定义了“启动”和“停止”两个按钮。另外,别忘了在AndroidMainfest.xml中注册Service:
<service android:name=". BindLocalServideextends "/> |
这里可以发现onBind需要返回一个IBinder对象。也就是说和上一例子LocalService不同的是:
1)添加了一个public内部类继承Binder,并添加getService方法来返回当前的Service对象;
2)新建一个IBinder对象——new那个Binder内部类;
3)onBind方法返还那个IBinder对象。
然后,我们来看看打印出来的效果,如图4-8所示:
图4-8 onBind Service执行顺序
通过日志,我们可以发现,通过bindService这种方法启动服务,当服务启动后,多次启动只有第一次有效,并且与服务相绑定的Activity“死亡”时,该服务也停止。
我们在使用某些Android应用的时候,可能会发现安装了某个应用之后,会有一些服务也会随之运行。而且,有的服务每次都会随着手机开机而自动启动。下面,就让我们一起来看看是怎么样实现开机自启动服务的。
首先,我们需要来了解一下Android中的 BroadcastReceiver:
BroadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播。
在Android系统中,广播应用在方方面面。例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;当网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度,等等。
正是基于这样的原理,只要实现一个BroadcastReceiver,我们就可以监听开机时候的广播(手机启动完成的事件ACTION_BOOT_COMPLETED),当收到开机“信号”时,启动相应的服务。
我们用一个简单的例子来看看它是如何实现的。
首先,我们新建一个MyReceiver类继承自BroadcastReceiver,代码如下:
// import略 public class MyReceiver extends BroadcastReceiver {
private static final String POWERN_ON_ACTION = "android.intent.action.BOOT_COMPLETED";
public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(POWERN_ON_ACTION)) { startService(new Intent("com.char4.LOCAL_SERVICE")); } } } |
我们要让这个Receiver工作,需要把它注册到Android系统上,去监听广播的BOOT_COMPLETED intent。在AndroidManifest.xml中添加如下代码:
<receiver android:name=".MyReceiver" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver> |
这样重新开机以后,服务就会在系统启动完毕后自动运行了。