Service是安卓四大组件之一,先前讲到了Service的生命周期,以及非绑定类型的生命周期的例子,这次来分享一下绑定形式的。

应用组件(客户端)可以调用bindService()绑定到一个service。Android系统之后调用service的onBind()方法,它返回一个用来与service交互的IBinder。

绑定是异步的,bindService()会立即返回,它不会返回IBinder给客户端。要接收IBinder,客户端必须创建一个ServiceConnection的实例并传给bindService()。ServiceConnection包含一个回调方法,系统调用这个方法来传递要返回的IBinder。

  • 实现ServiceConnection

实现必须重写两个回调方法:

onServiceConnected()

系统调用这个来传送在service的onBind()中返回的IBinder。

OnServiceDisconnected()

Android系统在同service的连接意外丢失时调用这个.比如当service崩溃了或被强杀了.当客户端解除绑定时,这个方法不会被调用。

  • 调用bindService(),传给它ServiceConnection的实现。

  • 当系统调用你的onServiceConnected()方法时,你就可以使用接口定义的方法们开始调用service了。

  • 要与service断开连接,调用unbindService()。

  • 程序                                                                                          

    public class MainActivity extends Activity {
    
        private Button btn_start;
    private Button btn_stop;
    private Button btn_change;
    private Button btn_bind;
    private Button btn_unbind; private MyConn myConn; private IService myBinder; @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main); btn_start = (Button) findViewById(R.id.btn_start);
    btn_stop = (Button) findViewById(R.id.btn_stop);
    btn_change = (Button) findViewById(R.id.btn_change);
    btn_bind = (Button) findViewById(R.id.btn_bind);
    btn_unbind = (Button) findViewById(R.id.btn_unbind);
    buttonListener bl = new buttonListener();
    btn_change.setOnClickListener(bl);
    btn_start.setOnClickListener(bl);
    btn_stop.setOnClickListener(bl);
    btn_bind.setOnClickListener(bl);
    btn_unbind.setOnClickListener(bl); } class buttonListener implements OnClickListener
    { @Override
    public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_start:
    Intent intent_start = new Intent(getApplicationContext(),BindService.class);
    startService(intent_start);
    break;
    case R.id.btn_stop:
    Intent intent_stop = new Intent(getApplicationContext(),BindService.class);
    stopService(intent_stop);
    break;
    case R.id.btn_change:
    if(myBinder != null)
    myBinder.doChange("啦啦啦");
    break;
    case R.id.btn_bind:
    if(myConn == null)
    {
    myConn = new MyConn();
    Intent intent_bind = new Intent(getApplicationContext(),BindService.class);
    bindService(intent_bind, myConn, BIND_AUTO_CREATE);
    }
    break;
    case R.id.btn_unbind:
    Intent intent_unbind = new Intent(getApplicationContext(),BindService.class);
    if(myConn != null && myBinder != null)
    {
    unbindService(myConn);
    myConn = null;
    myBinder = null;
    }
    break; default:
    break;
    } } } private class MyConn implements ServiceConnection
    { @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
    System.out.println("代理人返回回来了,onServiceConnected");
    myBinder = (IService) service; } @Override
    public void onServiceDisconnected(ComponentName name) {
    System.out.println("接触绑定了,onServiceDisconnected"); } } }

    Service类:

    public class BindService extends Service {
    
        @Override
    public IBinder onBind(Intent intent) {
    System.out.println("Service绑定成功,onBind");
    //返回自定义的代理对象
    return new MyBinder();//这里的返回是返回到MainActivity里面的绑定myConn
    } @Override
    public boolean onUnbind(Intent intent) {
    System.out.println("Service解绑成功,onUnbind");
    return super.onUnbind(intent);
    } public class MyBinder extends Binder implements IService
    {
    //间接的利用代理人调用了changeServiceThing的方法
    public void doChange(String what)
    {
    changeServiceThing(what);
    }
    } @Override
    public void onCreate() {
    System.out.println("Service开启,onCreate");
    super.onCreate();
    } @Override
    public void onDestroy() {
    System.out.println("Service关闭,onDestroy");
    super.onDestroy();
    } public void changeServiceThing(String what)
    {
    Toast.makeText(getApplicationContext(), what+"变换了,changeServiceThing", Toast.LENGTH_LONG).show();
    } }

    IService:

    public interface IService {
    public void doChange(String what);
    }

    结果                                                                                           

    点击“开启服务”之后,再“绑定服务”,这样执行之后直接点“关闭服务”是没用的,要先“解除服务”,再“关闭服务”。如果直接“绑定服务”,那么点击“关闭服务”没有用,需要点击“解绑服务”。

    aidl                                                                                           

    进程间通信->调用者和Service如果不在一个进程内,就需要使用android中的远程Service调用机制。

    android使用AIDL定义进程间的通信接口。AIDL的语法与java接口类似,需要注意以下几点:

    • AIDL文件必须以.aidl作为后缀名。
    • AIDL接口中用到的数据类型, 除了基本类型, String, List, Map, CharSequence之外, 其他类型都需要导包, 即使两种在同一个包内. List和Map中的元素类型必须是AIDL支持的类型。
    • 接口名需要和文件名相同。
    • 方法的参数或返回值是自定义类型时, 该自定义的类型必须实现了Parcelable接口。
    • 所有非java基本类型参数都需要加上in, out, inout标记, 以表明参数是输入参数, 输出参数, 还是输入输出参数。
    • 接口和方法前不能使用访问修饰符和static, final等修饰。

    进程间通信需要创建aidl文件,IService.aidl:

    public interface IService {
    public void doChange(String what);
    }

    接口中有一个static的抽象内部类Stub,Stub类继承了Binder类并实现了IRemoteService接口。

    public class MainActivity extends Activity {
    
        private Intent intent;
    private IService iService;
    private ServiceConnection myConn; @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main); } public void bind(View view) {
    intent = new Intent();
    intent.setAction("com.yydcdut.alipay");
    myConn = new MyConn();
    boolean flag = bindService(intent, myConn, BIND_AUTO_CREATE);
    System.out.println("flag------>" + flag);
    } private class MyConn implements ServiceConnection {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
    iService = IService.Stub.asInterface(service);
    } @Override
    public void onServiceDisconnected(ComponentName name) {
    }
    } public void method(View view) {
    try {
    iService.callMethodInService();
    } catch (RemoteException e) {
    // TODO 自动生成的 catch 块
    e.printStackTrace();
    }
    } }

    在实现这个的时候我建立了两个程序,这样可以做到进程间通信。附带了源码。

    我是天王盖地虎的分割线                                                               

    源代码:http://pan.baidu.com/s/1dD1Qx01

    service学习2.zip

    aidl学习.zip

    aidl学习配套2.zip

    转载请注明出处:http://www.cnblogs.com/yydcdut

Android -- Service绑定解绑和aidl的更多相关文章

  1. linux控制USB的绑定/解绑

    linux控制USB的绑定/解绑 http://www.jianshu.com/p/57293f9be558 今天工作中遇到一个问题, 要用代码实现USB的enable和disable. 谷歌了一番, ...

  2. jQuery---jQ动画(普通,滑动,淡入淡出,自定义动画,停止动画),jQuery的事件,jQ事件的绑定/解绑,一次性事件,事件委托,事件冒泡,文档加载

    jQuery---jQ动画(普通,滑动,淡入淡出,自定义动画,停止动画),jQuery的事件,jQ事件的绑定/解绑,一次性事件,事件委托,事件冒泡,文档加载 一丶jQuery动画 show,hide, ...

  3. Android Service 详解

    一个Service也是一种应用程序组件,它运行在后台以提供某种服务,通常不具有可见的用户界面.其它的应用程序组件可以启动一个 Service,即使在用户切换到另外一个应用程序后,这个Service还是 ...

  4. Android Service详解

    service作为四大组件值得我们的更多的关注 在Android中,Activity主要负责前台页面的展示,Service主要负责需要长期运行的任务.例如,一个从service播放音乐的音乐播放器,应 ...

  5. 手写instanceof (详解原型链) 和 实现绑定解绑和派发的事件类

    A  instanceof  B    是判断  A  是否继承自B,是返回true,  否返回false 再精确点就是判断B   是否  再  A  的 原型链上, 什么是原型链,举个例子: 我们定 ...

  6. bind() unbind()绑定解绑事件

    .bind( eventType [, eventData], handler(eventObject)) 本文实例分析了JQuery中Bind()事件用法.分享给大家供大家参考.具体分析如下: .B ...

  7. 19 01 16 jquery 的 属性操作 循环 jquery 事件 和事件的绑定 解绑

    jquery属性操作 1.html() 取出或设置html内容 // 取出html内容 var $htm = $('#div1').html(); // 设置html内容 $('#div1').htm ...

  8. Android总结篇系列:Android Service

    Service通常总是称之为“后台服务”,其中“后台”一词是相对于前台而言的,具体是指其本身的运行并不依赖于用户可视的UI界面,因此,从实际业务需求上来理解,Service的适用场景应该具备以下条件: ...

  9. Android -- service的开启方式, start开启和绑定开启服务,调用服务的的方法, aidl调用远程服务

    1. 概述 bindService() 绑定服务  可以得到服务的代理人对象,间接调用服务里面的方法. 绑定服务: 间接调用服务里面的方法.           如果调用者activity被销毁了, ...

随机推荐

  1. 第一个ajax小demo

    第一个ajax小demo 文章来源:http://blog.csdn.net/magi1201/article/details/44569657

  2. UVA12995 Farey Sequence [欧拉函数,欧拉筛]

    洛谷传送门 Farey Sequence (格式太难调,题面就不放了) 分析: 实际上求分数个数就是个幌子,观察可以得到,所求的就是$\sum^n_{i=2}\phi (i)$,所以直接欧拉筛+前缀和 ...

  3. FastReport.Net使用:[38]关系的使用

    打印所有成绩 1. 数据源准备 接下来我们需要打印学生成绩,而成绩表中无姓名,我们通过建立Realtion关系来打印数据. 2. 创建Relation关系 在数据视图上的动作下拉菜单中选择“新建关系” ...

  4. 【BZOJ 3998】 3998: [TJOI2015]弦论 (SAM )

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2627  Solved: 881 Description 对于一 ...

  5. luogu P4115 Qtree4

    题目链接 luogu P4115 Qtree4 题解 动态点分治,和上一题一样.同样三个堆.就是带权,用边权替换深度就好 为什么要单独写这个题解呢,因为我卡常卡了一天....据说树剖比rmq快? 在第 ...

  6. luogu P1809 过河问题_NOI导刊2011提高(01)

    题目描述 有一个大晴天,Oliver与同学们一共N人出游,他们走到一条河的东岸边,想要过河到西岸.而东岸边有一条小船. 船太小了,一次只能乘坐两人.每个人都有一个渡河时间T,船划到对岸的时间等于船上渡 ...

  7. BZOJ1084 SCOI2005最大子矩阵

    考虑DP f[i][j][k]表示一行到i一行到j共取k块最大值,类似于最长公共子序列n^2那种 注意相等时可以一起拿 By:大奕哥 #include<bits/stdc++.h> usi ...

  8. struts2漏洞S2-046修复解决方案

    项目验收通过半年之后, 甲方找了一些网络砖家用工具扫描我司做的社保卡申领系统, 找到了struts2漏洞S2-046, 真是服了, 只知道struts2有bug, 现在才知道它漏洞. 砖家们给出了修复 ...

  9. hdu 3435 图回路分割

    将一个无向图分成许多回路,回路点交集为空,点幷集为V.幷最小化回路边权和. #include <cstdio> #include <cstring> #include < ...

  10. 数组中找出最小的K个数

    题目 给出一个数组,找出K个最小的值 例如给出数组{5,2,4,3,1},给定K值3,则输出结果为{2,3,1} 程序 先给出第一个版本的程序 public static void printKNum ...