现在需要在一个独立于进程的Service中做一些操作, 同时要能在外部调用这个服务做一些事情.
使用bindService调用没有问题,问题是Activity或者App结束后Service也就结束了.
列一下规则:
操作a----退出-----服务运行否
1,bind: no
2,bind--unbind: no
3,start: yes
4,start--bind: yes
5,start--bind--unbind: yes
Activity想控制Service,还是必须使用bind,所以先start,再bind,既能保证其生命周期,又能进行调用.
或者把bind操作放在Service的调用之前,然后在new ServiceConnection 的onServiceConnected方法内bindservice,然后可用binder对Service进行操作.
下边贴上代码,关键是Service中自定义一个Binder的子类,里边有需要实现的方法.
然后在Activity中创建一个ServiceConnection对象,重写onServiceConnected回调方法,方法中可得到从Service中传过来的Ibinder对象.
Activity类
public class BindServiceTest extends Activity { Button bind, unbind, getServiceStatus, start; Button showToast, callFromStart; // 保持所启动的Service的IBinder对象 BindService.MyBinder binder; Boolean isRunning; // 定义一个ServiceConnection对象 private ServiceConnection conn = new ServiceConnection() {// *****************创建conn****************** // 当该Activity与Service连接成功时回调该方法 @Override public void onServiceConnected(ComponentName name, IBinder service) { System.out.println("--Service Connected--"); // 获取Service的onBind方法所返回的MyBinder对象 binder = (BindService.MyBinder) service; // ① // binder.getServiceInstance().showToast(); // unbindService(conn); } // 当该Acwwwtivity与Service断开连接时回调该方法 @Override public void onServiceDisconnected(ComponentName name) { System.out.println("--Service Disconnected--"); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取程序界面中的start、stop、getServiceStatus按钮 bind = (Button) findViewById(R.id.bind); unbind = (Button) findViewById(R.id.unbind); getServiceStatus = (Button) findViewById(R.id.getServiceStatus); showToast = (Button) findViewById(R.id.call); start = (Button) findViewById(R.id.start); callFromStart = (Button) findViewById(R.id.call_start); // 创建启动Service的Intent final Intent intent = new Intent(); // 为Intent设置Action属性 intent.setAction("org.crazyit.service.BIND_SERVICE"); start.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { startService(intent); } }); callFromStart.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { bindService(intent, conn, Service.BIND_AUTO_CREATE); } }); showToast.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { binder.getServiceInstance().showToast(); //**************调用Service中的方法********************* } }); bind.setOnClickListener(new OnClickListener() { @Override public void onClick(View source) { // 绑定指定Serivce bindService(intent, conn, Service.BIND_AUTO_CREATE);//******************绑定conn***************** } }); unbind.setOnClickListener(new OnClickListener() { @Override public void onClick(View source) { // 解除绑定Serivce unbindService(conn); } }); final ActivityManager manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); for (ActivityManager.RunningServiceInfo service11:manager.getRunningServices(Integer.MAX_VALUE)) { Log.v("xxxxxxxxx",BindService.class.getName()+"****"+service11.service.getClassName()); if (BindService.class.getName().equals( service11.service.getClassName())) { isRunning = true; } } getServiceStatus.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 获取、并显示Service的count值 isRunning = false; for (ActivityManager.RunningServiceInfo service11:manager.getRunningServices(Integer.MAX_VALUE)) { Log.v("xxxxxxxxx",BindService.class.getName()+"****"+service11.service.getClassName()); if (BindService.class.getName().equals( service11.service.getClassName())) { isRunning = true; } } Toast.makeText(BindServiceTest.this, "Serivce在运行吗:" +String.valueOf(isRunning), Toast.LENGTH_SHORT).show(); // ② } }); } }
Service类:
public class BindService extends Service { private int count; private boolean quit; // 定义onBinder方法所返回的对象 private MyBinder binder = new MyBinder(); // 通过继承Binder来实现IBinder类 public class MyBinder extends Binder // ① { public int getCount() { // 获取Service的运行状态:count return count; } public BindService getServiceInstance() { return BindService.this; } } //// Service被startService时回调该方法。 @Override public int onStartCommand(Intent intent, int flags, int startId) { Toast.makeText(this, "Service is Started", Toast.LENGTH_SHORT).show(); return super.onStartCommand(intent, flags, startId); } // 必须实现的方法,绑定该Service时回调该方法 @Override public IBinder onBind(Intent intent) { System.out.println("Service is Binded"); // Toast.makeText(this, "Service is Binded", Toast.LENGTH_SHORT).show(); // 返回IBinder对象 return binder; } // Service被创建时回调该方法。 @Override public void onCreate() { super.onCreate(); System.out.println("Service is Created"); // Toast.makeText(this, "Service is Created", Toast.LENGTH_SHORT).show(); // 启动一条线程、动态地修改count状态值 new Thread() { @Override public void run() { while (!quit) { try { Thread.sleep(1000); } catch (InterruptedException e) { } count++; } } }.start(); } // Service被断开连接时回调该方法 @Override public boolean onUnbind(Intent intent) { System.out.println("Service is Unbinded"); // Toast.makeText(this, "Service is Unbinded", Toast.LENGTH_SHORT).show(); return true; } // Service被关闭之前回调该方法。 @Override public void onDestroy() { super.onDestroy(); this.quit = true; System.out.println("Service is Destroyed"); Toast.makeText(this, "Service is Destroyed", Toast.LENGTH_SHORT).show(); } public void showToast() { Toast.makeText(this, "这是Service内部的一个方法", Toast.LENGTH_SHORT).show(); } }