Android -- Service绑定解绑和aidl

简介:

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/p/3810816.html,如需转载请自行联系原作者

相关文章
|
8月前
|
调度 Android开发
43. 【Android教程】服务:Service
43. 【Android教程】服务:Service
73 2
|
6月前
|
编解码 网络协议 Android开发
Android平台GB28181设备接入模块实现后台service按需回传摄像头数据到国标平台侧
我们在做Android平台GB28181设备对接模块的时候,遇到这样的技术需求,开发者希望能以后台服务的形式运行程序,国标平台侧没有视频回传请求的时候,仅保持信令链接,有发起视频回传请求或语音广播时,打开摄像头,并实时回传音视频数据或接收处理国标平台侧发过来的语音广播数据。
|
8月前
|
Android开发 Kotlin
Android面试题 之 Kotlin DataBinding 图片加载和绑定RecyclerView
本文介绍了如何在Android中使用DataBinding和BindingAdapter。示例展示了如何创建`MyBindingAdapter`,包含一个`setImage`方法来设置ImageView的图片。布局文件使用`<data>`标签定义变量,并通过`app:image`调用BindingAdapter。在Activity中设置变量值传递给Adapter处理。此外,还展示了如何在RecyclerView的Adapter中使用DataBinding,如`MyAdapter`,在子布局`item.xml`中绑定User对象到视图。关注公众号AntDream阅读更多内容。
131 1
|
9月前
|
存储 监控 Java
Android Service之设备存储空间监控 DeviceStorageMonitorService
Android Service之设备存储空间监控 DeviceStorageMonitorService
177 2
|
8月前
|
大数据 Android开发
Android使用AIDL+MemoryFile传递大数据
Android使用AIDL+MemoryFile传递大数据
119 0
|
9月前
|
Android开发 数据库管理
Android如何在Activity和Service之间传递数据
Android如何在Activity和Service之间传递数据
345 3
|
9月前
|
Android开发
Android AIDL 的使用
Android AIDL 的使用
59 1
|
9月前
|
Android开发
Android stdio 无法新建或打开AIDL文件(解决方法)
Android stdio 无法新建或打开AIDL文件(解决方法)
754 0
|
Android开发
【Android 进程保活】应用进程拉活 ( 系统 Service 机制拉活 | Service 组件 onStartCommand 方法分析 | 源码资源 )(三)
【Android 进程保活】应用进程拉活 ( 系统 Service 机制拉活 | Service 组件 onStartCommand 方法分析 | 源码资源 )(三)
354 0
【Android 进程保活】应用进程拉活 ( 系统 Service 机制拉活 | Service 组件 onStartCommand 方法分析 | 源码资源 )(三)
|
Android开发
【Android 进程保活】应用进程拉活 ( 系统 Service 机制拉活 | Service 组件 onStartCommand 方法分析 | 源码资源 )(二)
【Android 进程保活】应用进程拉活 ( 系统 Service 机制拉活 | Service 组件 onStartCommand 方法分析 | 源码资源 )(二)
290 0

热门文章

最新文章

  • 1
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 2
    Android历史版本与APK文件结构
  • 3
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
  • 4
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 5
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 6
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 7
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 8
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 9
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 10
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
  • 1
    Android实战经验之Kotlin中快速实现MVI架构
    18
  • 2
    即时通讯安全篇(一):正确地理解和使用Android端加密算法
    22
  • 3
    escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
    39
  • 4
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    113
  • 5
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    40
  • 6
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    54
  • 7
    Android历史版本与APK文件结构
    147
  • 8
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    46
  • 9
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    39
  • 10
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
    66