Android AIDL 与 Service

Android AIDL:跨进程调用Service (AIDL Service) 有任何问题,欢迎广大网友一起来交流,分享高阶Android学习视频资料和面试资料包~偷偷说一句:群里高手如云,欢迎大家加群和大佬们一起交流讨论啊!《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!erride@Override// …@Override@Override有任何问题,欢迎广大网友一起来交流,分享高阶Android学习视频资料和面试资料包~偷偷说一句:群里高手如云,欢迎大家加群和大佬们一起交流讨论啊! 阅读详情

一.首先介绍常见的Activity与Service建立通信的方式:

1.创建MyService:

public class MyService extends Service {
    
    MyBinder mMyBinder = new MyBinder();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mMyBinder;
    }
    //Binder是IBinder的实现类,通过简单继承Binder,再添加自定义的方法,可用于与Client(大多数场景是Activity)进行通信。
    public class MyBinder extends Binder {   
                 //获取当前的进程id,每个进程有唯一的pid值,用于区分不同进程
        public int getPid(){
            return Process.myPid();
        }
    }
    
}

2.在AndroidManifest.xml中注册刚刚创建的Service.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="netease.com.canvasdemo"
    android:versionCode="100">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".ClientActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

       <span style="color:#ff0000;"> <service android:name=".MyService">
            <intent-filter>
                <action android:name= "netease.com.aidldemo.MyService"/>
            </intent-filter>
        </service></span>

    </application>

</manifest>

3.在Client中进行绑定调用。

public class ClientActivity extends Activity {

    private MyService.MyBinder mBinder;

    private ServiceConnection con = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("ClientActivity", "onServiceConnected");
            try {
                mBinder = (MyService.MyBinder) service;
                int pid = mBinder.getPid();
                Log.d("ClientActivity", "currentPid:" + Process.myPid() + ",ServicePid:" + pid);
            }catch (Exception e){
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = new Intent("netease.com.aidldemo.MyService");
        bindService(intent, con, BIND_AUTO_CREATE);
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(con);
    }
}

运行应用,我们可以在logcat中看到输出结果

D/ClientActivity: onServiceConnected
D/ClientActivity: currentPid:25788,ServicePid:25788
这一结果证明,Service与Activity运行在相同的进程中。


二.指定Service进程

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="netease.com.canvasdemo"
    android:versionCode="100">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".ClientActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".MyService" <span style="color:#ff0000;">android:process="com.netease.service"</span>>
            <intent-filter>
                <action android:name= "netease.com.aidldemo.MyService"/>
            </intent-filter>
        </service>

    </application>

</manifest>
红色为新增的属性,通过指定process属性即可让Service控件运行在不同的进程中。

我们直接运行发现程序崩溃了

W/System.err: java.lang.ClassCastException: <span style="color:#ff0000;">android.os.BinderProxy cannot be cast to netease.com.canvasdemo.MyService$MyBinder</span>
 at netease.com.canvasdemo.ClientActivity$1.onServiceConnected(ClientActivity.java:24)
 at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1101)
 at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1118)
 at android.os.Handler.handleCallback(Handler.java:733)
 at android.os.Handler.dispatchMessage(Handler.java:95)
 at android.os.Looper.loop(Looper.java:136)
 at android.app.ActivityThread.main(ActivityThread.java:5001)
 at java.lang.reflect.Method.invokeNative(Native Method)
 at java.lang.reflect.Method.invoke(Method.java:515)
 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
 at dalvik.system.NativeStart.main(Native Method)
我们根据错误的行数定于到出错的地点,发现是在Activity中的红色这一行:

 private ServiceConnection con = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("ClientActivity", "onServiceConnected");
            try {
                <span style="color:#ff0000;">mBinder = (MyService.MyBinder) service;</span>
                int pid = mBinder.getPid();
                Log.d("ClientActivity", "currentPid:" + Process.myPid() + ",ServicePid:" + pid);
            }catch (Exception e){
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };
说明在我们指定process时,传回来的IBinder实例对象发生了改变。现在传回来的实例是 android.os.BinderProxy,而不是原来的MyService.MyBinder实例了.  (笔者现在只了解,这应该是Android底层实现的代理类,用来实现跨进程通信,具体的实现方式,在下一篇博客中进行分析)。那么跨进程通信即IPC的正确打开方式是什么呢?我们来马上介绍。

三.通过AIDL来实现跨进程通信

1.创建AIDL文件


我们输入文件名IDownload,会自动生成aidl文件,我们在其中添加 int getPid(); void basicType()是自动生成的,我们可以留着作为测试。


然后点击 Build-> Make Project 编译,在build generated中我们能看到自动生成的IDownload接口,这个文件中比较重要的是内部抽象类Stub,这个类继承自Binder并且实现了我们在aidl文件中定义的接口。



然后我们回到MyService中,修改MyBinder继承至IDownload.Stub

public class MyService extends Service {

    MyBinder mMyBinder = new MyBinder();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mMyBinder;

    }

    public class MyBinder extends IDownload.Stub {

        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
            // 后续再使用
        }

        public int getPid(){
            return Process.myPid();
        }
    }

}

回到Activity中,修改红色部分

public class ClientActivity extends Activity {

    private <span style="color:#ff0000;">IDownload</span> mBinder;

    private ServiceConnection con = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("ClientActivity", "onServiceConnected");
            try {
                mBinder =  <span style="color:#ff0000;">IDownload.Stub.asInterface(service);</span>
                int pid = mBinder.getPid();
                Log.d("ClientActivity", "currentPid:" + Process.myPid() + ",ServicePid:" + pid);
            }catch (Exception e){
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = new Intent("netease.com.aidldemo.MyService");
        bindService(intent, con, BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(con);
    }
}
这个时候,我们再次启动应用,发现不再报错了。

D/ClientActivity: onServiceConnected
D/ClientActivity: currentPid:21429,ServicePid:21442
根据pid不同,也确实验证了,此时的Service,运行在了与Activity不同的线程。

我们把AndroidManifest中 service 的 process属性去掉再试试。

D/ClientActivity: onServiceConnected
D/ClientActivity: currentPid:21999,ServicePid:21999
此时pid又相同了。

根据以上的实验,我们可以得出以下结论:

在同一个应用内:

1.不单独指定Service进程(AndroidManifest中指定Service的process属性),Activity中可通过ServiceConnect回调中 IBinder强转为自定义的MyBinder进行回调。

2.若单独指定Service进程,将ServiceConnect回调中 IBinder强转为实现类MyBinder时,会报错。(因为此时是通过代理Binder来实现跨进程通信,而不是自己定义的MyBinder,所以强转会报类型转换错误)

3.第2点中的错误,可通过定义AIDL接口的方式解决(假如定义了IDownload.aidl),此时想拿到IBinder的实现类,需要通过调用IDownload.Stub.asInstance(IBinder),这样就能实现跨进程通信。

最后AIDL既然能实现跨进程通信,其实也是能够实现不同应用之间的通信的。但是笔者实验过程中,发现会报错,目前仍在调试,先把使用方式总结下。

不同应用:

不同应用,可以使用相同的AIDL定义的接口,来进行通信。假如B应用中创建了AIDL及Service类,应用A,中只需拷贝B中的AIDL文件(包名保持一致)即可与应用B进行通信。原理类似于上述第3条。


安卓native service与app通过AIDL通信 android系统中native service与app位于不同的进程,可以通过AIDL进行交互传输数据。少量的数据可以用AIDL直接传输,如果是大量的数据如传输一张图片超过1M的数据话就不能用AIDL直接传了,大的数据用AIDL传输会比较慢,另外AIDL是有传输大小限制的,不适合大的数据传输。大的数据可以用共享内存来传,但注意要控制好读写共享内存时的同步问题。 native service需要添加到ServiceManager中,上层app可以通过反射获取ServiceManager连接native s 阅读详情

相关推荐

Android Studio中创建AIDL Service

用startService,bindService创建的服务只能在本应用程序内访问,如果要使得本程序的服务能够被其他应用程序访问,这时候就要使用远程过程调用(Remote Procedure Call,RPC)方式来实现,安卓定义了一种接口定义语言Android Interface Definition Language,简称AIDL。今天记录一下如何在Android Studio下创建AID

laoxu的专栏 1万+

【Android】跨进程通信——AIDL、之Service基本细节使用之:精通

入门及高级进阶Android组件 Service

学习只为当小狗狗,学习只为当小狗狗,学习只为当小狗狗,学习只为当小狗狗,学习只为当小狗狗,学习只为当小狗狗,学习只为当小狗狗 7372

【Service 1】Android Remote Service - AIDL

背景Service作为Android的四大套件,其作用以及重要性都不必多说。在使用的过程中,UI模块(Activity)与Service的通讯是一个重要的话题。Activity和Service的关系可以分为两种: Activity与Service共享一个process,这种应该是最常见的情况。 Activity与Service不在同一个process中,如果它们在同一个app中但Service在ma

开发就是不断的发现不足与学习 1802

Android Framework之Service与AIDL学习

这个操作很简单,选择快捷创建方式,创建一个aidl 文件即可。Java 编程语言中的所有原语类型(如intlongcharboolean等)StringListList中的所有元素必须是以上列表中支持的数据类型,或者您所声明的由 AIDL 生成的其他接口或 Parcelable 类型。您可选择将List用作“泛型”类(例如,尽管生成的方法旨在使用List接口,但另一方实际接收的具体类始终是ArrayList。MapMap。

嘴巴吃糖了 658

掌握Android Service与AIDL开发:实例教程

Service是Android系统中的一种组件,它允许应用程序执行长时间运行的操作,而无需用户与界面交互。Service通常在后台运行,不提供用户界面。它们非常适合用于执行不需要用户直接交互的任务,例如音乐播放、文件下载或位置更新。AIDL(Android Interface Definition Language)是Android中用于进程间通信(IPC)的一种接口定义语言。它允许应用程序定义能被其他应用程序调用的接口。

weixin_34598113的博客 808

跟着Synopsys报告,一步步拆解车规芯片FMEDA计算(含公式与避坑点)

本文详细解析了车规芯片FMEDA计算的全流程,基于Synopsys报告拆解实战指南,涵盖基础失效率建模、安全机制效能评估及安全指标合成等关键步骤。通过公式解析、数据准备清单和避坑点分享,帮助工程师掌握ISO26262标准下的硬件量化分析技术,提升车载系统设计可靠性。

weixin_30460489的博客 195

Android service AIDL 使用笔记

在Android中加入AIDL支持,在build.gradle.kts中加入 aidl = true;

菜鸟笔记 967

扩增子分析|溯源分析在R中的复现:跟着Nature系列文章利用FEAST溯源分析包追溯微生物群落的起源

溯源分析由Liat Shenhav等人在2019年发表在Nature Methods杂志,他们开创的一种分析微生物群落组成结构的方法,通过量化不同微生物样本(来源)在目标微生物群落(汇)中的比例或分数识别微生物群落的潜在来源。该方法自发表以来受到微生物学界广泛关注,该论文截止2024年10月9日已经被引289次,是领域内高被引论文,该方法已经成为Nature,cell系列文章高度关注的方法。

weixin_46814750的博客 3434

Android Service 详解(包含AIDL)

Android Service 详解(包含AIDL) 博客参照< < Android开发全程实录> >的例子 , 以及其他博客, 希望能给学习Android Service的小伙伴一个比较详细的解释与实践 Service简介简介生命周期Service的生命周期比Activity的简单, 只有3个: - 创建服务: onCreate() - 启动服务: onStart() - 销毁服务: o

Daker's Blog 2123

ROS Noetic下Gazebo仿真:从零搭建两轮差速机器人(含ros_control配置避坑指南)

本文详细介绍了在ROS Noetic环境下,使用Gazebo从零搭建两轮差速机器人并进行仿真的完整流程。核心内容包括利用Xacro进行模块化建模,并重点解析了通过ros_control框架配置机器人运动控制的详细步骤与常见避坑指南,帮助开发者成功实现机器人在仿真环境中的差速驱动与运动控制。

game4的博客 620

LTM4644 四通道并联 16A 输出配置:PCB 布局 3 要点与热仿真验证

本文详细解析了LTM4644四通道并联实现16A输出的PCB布局与热管理要点,包括电流路径对称性设计、热优化布局技巧和接地系统优化。通过实际工程案例,展示了如何确保电流均流、热分布均衡及长期可靠性,为FPGA、ASIC和服务器主板供电设计提供高效解决方案。

weixin_33314040的博客 398

Android Service 与 AIDL 详解

服务的基本用法 Service 是安卓四大组件之一,Activity 一般有具体的用户界面,而 Service 则是 Android 实现程序后台运行的解决方案。那些不需要与用户交互,或者需要长期运行的任务,就适合使用服务。服务的特性如下 服务并不能独立运行,而是依靠某个进程创建,该进程被杀死,服务也就不复存在 服务不会自动开启线程,默认是在主线程中运行。如果不手动在服务的内部创建子线程,很可能...

个人笔记 2392

VHDL语法学习笔记:一文掌握VHDL语法

今天给大侠带来FPGA 之 VHDL 语法学习笔记,话不多说,上货。 VHDL语法学习笔记 一、VHDL简介 1.1 VHDL 的历史 VHDL 的 英 文 全 名 是 Very-High-Speed Integrated Circuit Hardware DescriptionLanguage,诞生于 1982 年。 1987 年底,VHDL 被 IEEE 和美国国防部确认为标准硬件描述语言。自 IEEE 公布了 VHDL 的标准版本 IEEE-1076(简称 87 版)...

2万+

基于AIDL编程实现Android远程Service服务

文章目录Android本地Service异步消息处理机制服务与活动的通信Android远程ServiceBinder与AIDL基础AIDL Service服务端 Service 作为 Android 四大组件之一,应用非常广泛。 远程服务与本地服务最大的区别是:远程 Service 与调用者不在同一个进程里(即远程 Service 是运行在另外一个进程);而本地服务则是与调用者运行在同一个进程里。二者区别的详细区别如下图: Android本地Service 先来看看 Android 普通 Service

道阻且长,行则将至 4416

功能安全实战系列07-英飞凌TC3xx电源监控开发详解

本文对电源监控(PBIST及MONBIST)开发介绍,步骤详细配合开发中的测试情况,图文并茂,方便理解。

initiallizer的博客 1109

【VTKExamples::Meshes】第十二期 QuadricDecimation

本文分享VTK样例QuadricDecimation,并解析接口vtkQuadricDecimation,希望对各位小伙伴有所帮助!

qq_40041064的博客 343

android service 和aidl

前言:苦逼的楼猪被抓去sql 和aidl 了 哎真是辛苦啊,要求是这样的设立一个android 数据库 能够给多个apk 调用。想了下只能用android service 和aidl 了 了解下anroid service:  楼猪 尊重版权:http://coolxing.iteye.com/blog/1222602/ Service是android中的服务组件

激情的蜗牛的专栏 700

【AHE数据集】历史/未来全球网格热排放数据 PF-AHF

AHE数据集

WW、forever的博客 127

android studio aidl 编译,Android Studio实现Service AIDL

今天要开发过程中要用到AIDL的调用,之前用的eclipse有大量教程,用起来很方便,现在刚换了Android studio,不可否认studio真的很强大,只是很多功能还需要摸索。AIDL(Android Interface Definition Language)是Android接口定义语言的意思,它可以用于让某个Service与多个应用程序组件之间进行跨进程通信,从而可以实现多个应用程序共享...

weixin_35589806的博客 564

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Android AIDL:跨进程调用Service (AIDL Service),大厂Android开发面试解答

1. 相关知识点 Android系统中的进程之间不能共享内存,需要提供一些机制在不同进程之间进行数据通信,这个机制就是AIDL。 1. AIDL: Android Interface definition language Android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口。 2. IPC:interprocess communication (内部进程通信) 3. 如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可

wq221aas的博客 2923

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Android Service AIDL

Service AIDL简述 Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。Android应用程序组 件中的4个(Activity、Broadcast、 Service和Content Provider)都可以进行跨进程访问,Service就是通过AIDL服务来 完成不同进程之间的通信。 在AIDL服务中有两种对象:   服

Code-lover's Learning Notes 1340

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Android进阶之Service远程通信AIDL

Service的远程通信AIDL先解释下什么是AIDL,AIDL (Android Interface Definition Language)是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。AIDL IPC机制是面向接口

一大三千的博客 1803

Android Binder与AIDL与Service使用案例及分析

摘要:Binder是Android高效的跨进程通信机制,通过AIDL工具简化开发。核心流程包括:1)定义AIDL接口并生成Stub类;2)服务端继承Stub实现逻辑,通过Service的onBind返回Binder对象;3)客户端通过ServiceConnection获取代理对象进行跨进程调用。关键点在于:必须依托Service实现进程隔离,使用RemoteCallbackList管理回调,注意注册/解注册防止内存泄漏。底层通过Binder驱动(内核缓冲区+进程映射)实现数据拷贝和跨进程方法调用,Servi

童年纸飞机的博客 1283

37.Android Service 及 AIDL

37.Android Service 及 AIDLAndroid Service 及 AIDL Android Service介绍 Android Service类型 Android Service bind 和 start Local Service 实现 Remote Service 实现Android Service介绍├── Context │ ├── ContextWrapper (S

Save you from anything 4062

android动态加载service,安卓四大组件之二#2-使用AIDL技术实现动态调用其他app中的Service的方法...

上次我给大家介绍了Service的基本用法,其中有提到过如何访问自身app的Service,现在我来为大家介绍如何访问其他app的Service1:创建一个安卓项目app1并且新建一个service,在Service清单文件中配置访问此服务所需要的过滤条件清单代码如下android:name="com.example.aidl.MyService"android:enabled="true"and...

weixin_32346177的博客 519
上一篇: 命令行java 找不到或无法加载主类
下一篇: Android Binder通信机制浅析
kkdev
博客等级 码龄11年 1粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值