安卓Service绑定方式启动服务并调用服务中的方法
来源:互联网 发布:联通数据卡流量查询 编辑:程序博客网 时间:2024/04/30 09:04
如有转载,请申明:
转载至 http://blog.csdn.net/qq_35064774/article/details/52578933
安卓的Service有两种启动方式,startService的方式非常简单,但相应的不能调用Service中的方法;而bindService的方式虽然复杂,但可以方便的调用Service中的方法。下面我们来介绍一下如何实现。
Service实现类
要开启服务,首先需要创建一个Service类。
下面是具体的Service实现类,看起来很多,但理解清楚后,发现还是很简单。
public class QuickStartService extends Service { /** * 绑定服务的时候会调用 * @param intent * @return */ @Override public IBinder onBind(Intent intent) { System.out.println("onBind"); return new Agent();} /** * 服务创建时调用 */ @Override public void onCreate() { super.onCreate(); System.out.println("service onCreate"); } /** * 通过startService启动服务时调用 * @param intent * @param flags * @param startId * @return */ @Override public int onStartCommand(Intent intent, int flags, int startId) { System.out.println("service onStartCommand"); return super.onStartCommand(intent, flags, startId); } /** * 服务销毁时调用 */ @Override public void onDestroy() { super.onDestroy(); System.out.println("service onDestroy"); } /** * 自己编写的服务中的方法,我们需要在启动服务后,特定时间调用 * @param name */ public void serviceMethod(String name) { System.out.println("service serviceMethod"); Toast.makeText(QuickStartService.this, name + "你好,你的证已经办好了", Toast.LENGTH_SHORT).show(); } /** * 对外公开的服务方法调用接口 */ public interface IService { void callServiceMethod(String name, int money); } /** * 服务类中私有的代理类,可以直接与服务类相互调用的类,但同时实现了IService接口,所以把该对象传递给外部时,外部看起来就是一个IService的实现类 * 使用的是双接口的java技巧实现 对外公开部分方法 */ private class Agent extends Binder implements IService{ @Override public void callServiceMethod(String name, int money) { if(money < 150) { Toast.makeText(QuickStartService.this, "对不起 " + name + ",您不符合要求", Toast.LENGTH_SHORT).show(); return; } serviceMethod(name); } }}
首先onBind方法是继承Service后必须实现的抽象方法。这个方法的职责也很简单,就是把代理对象暴露给外界。
然后是Service的生命周期方法onCreate onStartCommand onDestroy
这几个方法里面,基本算是空实现,如果不清楚Service生命周期,可以看我另外的一篇专门介绍了。
除了上述方法,最后还剩下一个自己编写的serviceMethod方法,这个方法也很简单,就是Toast提示用户证已经办好了。
但是到这里还没结束,既然我们要调用自己编写的serviceMethod,而外界又拿不到启动后的服务的引用,我们只能通过“秘书”来实现了。
上面代码中的Agent 类就是这样一个“秘书”,它继承了Binder类,因此可以在onBind方法中返回Agent对象。并且还实现了IService,这样外界拿到Agent后,只能当作一个IService来使用,因为Agent是服务的内部私有类。而这里的IService接口的作用就不言而喻了。
绑定的Activity类
到这里,服务类编写完成。我们还需要一个外部类来绑定服务,调用服务中的方法。(相应的xml就不贴了,就三个Button)
public class ServiceQuickStartActivity extends AppCompatActivity implements View.OnClickListener { private QuickStartService.IService agent; private MyConnection connection; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_service_quick_start); init(); } /** * 控件事件绑定 */ private void init() { findViewById(R.id.btn_bind_service).setOnClickListener(this); findViewById(R.id.btn_call_service_method).setOnClickListener(this); findViewById(R.id.btn_unbind_service).setOnClickListener(this); } /** * 控件点击事件 * @param v */ @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_bind_service: bindService(); break; case R.id.btn_call_service_method: callServiceMethod(); break; case R.id.btn_unbind_service: unbindService(); break; } } /** * 调用服务中的方法,注意,需要先绑定服务 */ private void callServiceMethod() { if(null == agent) { Toast.makeText(ServiceQuickStartActivity.this, "请先绑定服务", Toast.LENGTH_SHORT).show(); return; } agent.callServiceMethod("小明", 180); } /** * 绑定服务,根据参数设置,可以在绑定时开启服务 */ private void bindService() { if(null != connection) { Toast.makeText(ServiceQuickStartActivity.this, "您已经绑定了服务,请勿重复绑定", Toast.LENGTH_SHORT).show(); return; } connection = new MyConnection(); Intent intent = new Intent(this, QuickStartService.class); if (bindService(intent, connection, Context.BIND_AUTO_CREATE)) Toast.makeText(ServiceQuickStartActivity.this, "绑定服务并开启成功", Toast.LENGTH_SHORT).show(); else Toast.makeText(ServiceQuickStartActivity.this, "绑定服务失败", Toast.LENGTH_SHORT).show(); } /** * 取消绑定服务 */ private void unbindService() { if(null == connection) { Toast.makeText(ServiceQuickStartActivity.this, "服务还未绑定", Toast.LENGTH_SHORT).show(); return; } unbindService(connection); connection = null; // 由于connection中的onServiceDisconnected方法只有在连接异常中断时才会调用,所以在解绑的时候,也要把代理对象置空 if(null != agent) { agent = null; } Toast.makeText(ServiceQuickStartActivity.this, "取消绑定服务成功", Toast.LENGTH_SHORT).show(); } /** * 绑定服务的连接类 */ private class MyConnection implements ServiceConnection { /** * 当与服务连接的调用 * @param name * @param service */ @Override public void onServiceConnected(ComponentName name, IBinder service) { // 连接成功后,会把代理人传递过来 agent = (QuickStartService.IService) service; System.out.println("onServiceConnected"); } @Override public void onServiceDisconnected(ComponentName name) { agent = null; System.out.println("onServiceConnected"); } }}
这个类看起来也有点多,但其实核心的是三个方法bindService callServiceMethod unbindService和一个类MyConnection。
首先,为了能够绑定服务,我们需要一个连接类MyConnection ,这里的方法是实现ServiceConnection接口的方法,onServiceConnected是当连接成功的时候,回调的方法,它负责把内部传递的代理类保存起来,onServiceDisconnected则是当连接断开时回调的。
有了连接类,我们就可以在bindService方法中绑定服务了,bindService(intent, connection, Context.BIND_AUTO_CREATE);调用这么一个api,就可以绑定服务,并自动开启。
剩下的是调用服务中的方法callServiceMethod,这个方法其实只是调用了保存的代理类对象的方法agent.callServiceMethod("小明", 180);
最后是解除绑定。
- 安卓Service绑定方式启动服务并调用服务中的方法
- 绑定服务并调用服务中的方法
- 安卓Service组件使用系列4:绑定service并调用service中的方法返回结果
- 安卓绑定本地服务Service并与之通信
- activity以绑定服务的方式开启服务并调用服务里面的方法
- 绑定服务:调用远程服务中的方法
- 绑定服务调用本地服务中的方法
- 绑定服务调用远程服务中的方法
- android五中方式调用服务service中的方法
- 绑定服务并调用服务的方法,解除绑定
- Android -- service的开启方式, start开启和绑定开启服务,调用服务的的方法, aidl调用远程服务
- 安卓 Service和绑定服务
- 绑定的方式调用服务的方法
- 安卓服务service全解,生命周期,前台服务、后台服务,启动注销、绑定解绑,注册
- Android启动服务和绑定服务的方法调用
- Android绑定方式开始服务&调用服务当中的方法
- 启动服务(Service)和调用服务里的方法
- Android Service 调用服务中的方法
- DOM特效之tab切换的实现
- hdu 1022 Train Problem I(栈)
- Android SoundPool.play方法的音量与系统音量的关系
- php过滤html标记属性类用法实例
- 文章标题
- 安卓Service绑定方式启动服务并调用服务中的方法
- 元素出入栈的合法性——栈和队列面试题(4)
- MarkDown常用语法总结
- weight decay and learning rate
- ios 线程
- 文章标题
- 通俗理解数据库设计原则
- TrieMap 实现
- Web前端工程化的实践思路(二)——Web前端工程化的基础