Android通过AIDL在两个APP之间Service通信

作者:小群子0618 时间:2022-04-15 23:58:27 

一、项目介绍

【知识准备】

①Android Interface definition language(aidl,android接口定义语言),其目的实现跨进程的调用。进程是程序在os中执行的载体,一个程序对应一个进程,不同进程就是指不同程序,aidl实现不同程序之间的调用。

②主线程与子线程通信使用handler,handler可以在子线程中发出消息,在主线程处理消息,从而完成线程之间的通信,即使有多个线程,仍然是一个程序。

③不同程序之间需要通过aidl通信,通信方式可以有多种,aidl是其中一种。实现的结果就像自己的程序调用自己的其他方法一样,感觉就像一个程序。

④业务场景:例如购物app需要支付,购物app是淘宝,支付app是支付宝。所以就需要不同的程序进行通信。 

二、首先介绍一个App之间的Service和Activity之间的通信

【项目结构】

Android通过AIDL在两个APP之间Service通信

【MyService】

【提示】

①创建Service

Android通过AIDL在两个APP之间Service通信

 ②如果不是通过上述方法创建,一定要记得注册


<service
android:name=".MyService"
android:enabled="true"
android:exported="true">

</service>

【代码】


public class MyService extends Service {
public MyService() {
}

@Override
public IBinder onBind(Intent intent) {
return new MyBinder();//return MyBinder通过ServiceConnection在activity中拿到MyBinder
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

return super.onStartCommand(intent, flags, startId);
}

public void payService(){
Log.i("MyService", "payService: --------");
}

class MyBinder extends Binder{

public void pay(){
payService();
}//通过Binder实例将service中的方法暴露出去
}
}

【layout_main】

添加按钮,点击便于调用


<Button
android:id="@+id/btn_paly"

android:text="Pay"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

【MainActivity】


public class MainActivity extends AppCompatActivity {

MyService.MyBinder binder = null;
ServiceConnection conn;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button btnPlay = (Button) findViewById(R.id.btn_paly);
conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
binder = (MyService.MyBinder) iBinder;
}

@Override
public void onServiceDisconnected(ComponentName componentName) {

}
};

Intent intent = new Intent(MainActivity.this,MyService.class);
bindService(intent,conn,BIND_AUTO_CREATE);//开启服务

btnPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (binder!=null){
 binder.play();
}
}
});
}
}

【效果】

Android通过AIDL在两个APP之间Service通信

点击后输出service中pay方法中的内容

Android通过AIDL在两个APP之间Service通信

 三、两个App之间的Service通信

【项目结构】

Android通过AIDL在两个APP之间Service通信

【步骤】

①在AppPayProvider中创建MyService

代码同上

【注册】

Ⅰ、注册时(android:enabled="true"   android:exported="true" )设置为true,将Service暴露出去,另一个App才能访问到它

Ⅱ、添加『 <intent-filter> 』。由于不是同一个App,通过intent-filter对Intent进行过滤,让另一个app通过action开启服务


<service
android:name=".MyService"
android:enabled="true"
android:exported="true">
<!--enable:ture设置可用
exported:ture对外暴露 -->
<intent-filter>
<action android:name="com.xqz.apppayprovider.MyService" />
</intent-filter>
</service>

②MainActivity和layout_main保留创建时不作任何修改,但也不要删掉,因为安装程序必须提供起始页面,否则将会出错

③在AppPayProvider中添加AIDL

Android通过AIDL在两个APP之间Service通信

【代码】

Android通过AIDL在两个APP之间Service通信

Android通过AIDL在两个APP之间Service通信

【提示】接口中定义中方法要和Service中的MyBinder中的方法一致

④再创建好AIDL,添加完方法后,android studio需要对这个aidl进行编译,会自动按aidl规范生成一个Binder子类的代码。

Android通过AIDL在两个APP之间Service通信

⑤对MyService中的MyBinder进行修改

Android通过AIDL在两个APP之间Service通信

【提示】继承IPay.Stub。在这之前必须Make Project,否则将没有只能联想

⑥创建AppPayUser对AppPayProvider中的MyService进行操作

【layout-main】


<Button
android:id="@+id/btnPay"
android:text="pay"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

⑦将AppPayProvider中AIDL拷贝到AppPayUser中

【提示】Ⅰ、包名要相同,按目录位置复制,通过下述方法,直接在文件夹进行复制。『此处可以查看项目结构,可以看到包名是相同的』

Ⅱ、同样拷贝过来后需要Make Project 

Android通过AIDL在两个APP之间Service通信

⑧【AppPayUser-MainActivity】


public class MainActivity extends AppCompatActivity {

Button btnPay;
private IPay myBinder;//定义AIDL

ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {

myBinder = IPay.Stub.asInterface(iBinder);
}

@Override
public void onServiceDisconnected(ComponentName componentName) {

}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Intent intent = new Intent();
intent.setAction("com.xqz.apppayprovider.MyService");
//表示按照什么进行过滤,启动意图
/*android5.0之后,如果servicer不在同一个App的包中,
需要设置service所在程序的包名
(包名可以到App的清单文件AndroidManifest中查看)*/
intent.setPackage("com.xqz.apppayprovider");
bindService(intent,conn,BIND_AUTO_CREATE);//开启Service

btnPay = (Button) findViewById(R.id.btnPay);

btnPay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
 myBinder.pay();
} catch (RemoteException e) {
 //因为是跨程序调用服务,可能会出现远程异常
 e.printStackTrace();
}
}
});
}
}

【安装】

先安装AppPayProvider再安装AppPayUser。

【效果】

将run中的 视图调到AppPayProvider,点击模拟器AppPayUser中的pay按钮,将会执行AppPayProvider中MyService中pay方法中的内容。

Android通过AIDL在两个APP之间Service通信

四、总结

【跨App和同App之间的区别】
①跨App开启服务是提供服务的App需要设置intent-filter过滤器,控制服务的App需要通过。setAction和setPackage方法进行设置action和包名,才能开启服务。而同App只需要指定启动的service就可。

②跨App的MyBinder实例要通过AIDL获取,两个应用定义同样的接口的方法,通过对应的AIDL名称.Stub.asInterface方法得到binder实例,然后就和同App的myBinder使用么有区别了。

③跨App的MyBinder对象的使用必须捕获异常,而同App不需要。

④可以根据上方简单的例子实现很多类似的功能。

来源:http://www.cnblogs.com/xqz0618/p/aidl_service.html

标签:Android,AIDL,APP,Service
0
投稿

猜你喜欢

  • Android实战APP启动速度优化

    2023-03-21 15:34:18
  • Java网络编程TCP实现聊天功能

    2023-12-01 17:05:35
  • 使用Files.walkFileTree遍历目录文件

    2021-09-27 06:12:40
  • springboot中通过lua脚本来获取序列号的方法

    2023-05-05 04:25:44
  • Java实现List集合转树形结构的示例详解

    2021-11-11 10:48:33
  • c#用for语句输出一个三角形的方法

    2023-12-17 05:46:53
  • maven为MANIFEST.MF文件添加内容的方法

    2022-10-29 11:15:56
  • SpringBoot配置文件中数据库密码加密两种方案(推荐)

    2023-03-16 22:40:55
  • 手动添加jar包进Maven本地库内的方法

    2023-08-03 03:10:09
  • c#异步操作async await状态机的总结(推荐)

    2021-08-22 07:13:12
  • MyBatis持久层框架的用法知识小结

    2022-05-21 17:12:55
  • ImageView 实现Android colorPikcer 选择器的示例代码

    2023-03-12 03:21:37
  • Kotlin编程基础语法编码规范

    2023-06-20 16:50:07
  • 详解LINQ入门(上篇)

    2023-10-15 05:57:30
  • Java8 用Lambda表达式给List集合排序的实现

    2023-02-05 17:27:09
  • Mybatis代码生成器Mybatis Generator(MBG)实战详解

    2023-12-02 23:04:31
  • C#获取每个年,月,周的起始日期和结束日期的方法

    2023-11-11 20:53:45
  • java并发之原子操作类和非阻塞算法

    2022-04-13 04:39:01
  • JDK14之jpackage打包命令的使用

    2022-09-29 19:57:19
  • 在Android系统中使用WebViewClient处理跳转URL的方法

    2021-08-03 14:24:59
  • asp之家 软件编程 m.aspxhome.com