之前上一篇讲解到本地服务,本地服务只能在自身APP中Activity访问Service,调用Service里面到方法等操作

如果想A应用访问B应用里面的方法,属于跨进程调用,如果Android不特供这种跨进程间通讯等API,是不能实现的

Google Android 为了解决 A应用--->B应用 跨进程访问通讯,提供了一种机制,就是IBInder,这种IBinder机制是Google工程师加入进去的,以前的Linux里是没有这个机制的

bindService 会返回IBinder接口,IBinder就是Google工程师在为了解决这种跨应用跨进程通讯,IBinder还需要结合Aidl才能实现远程服务(跨进程跨应用通讯)

注意:⚠️以前本地服务是通过显示意图去绑定,现在远程服务由于无法拿到另外应用的字节码,只能隐士意图去绑定

Service2,作为服务端,需要把MyService暴露出去

    <!--
android:process=":remote",代表在应用程序里,当需要该service时,会自动创建新的进程。
而如果是android:process="remote",没有“:”分号的,则创建全局进程,不同的应用程序共享该进程。
-->
<service android:name=".service.MyService"
android:exported="true"
android:enabled="true"
android:process=":remote"> <!-- 允许对外输出 --> <!-- 想要其他应用程序可以访问我的访问,就必须要对外暴漏 -->
<intent-filter> <action android:name="liudeli.service2.service.MyService" /> </intent-filter> </service>

Service2,把逻辑都卸载MyService

package liudeli.service2.service;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException; import liudeli.service2.IMusician;
import liudeli.service2.service.inter.ISinger; public class MyService extends Service { @Override
public IBinder onBind(Intent intent) {
// return new MyBinder(); 以前这种方式只适合本地服务(自身APP)
return new MyBinderAidl();
} /**
* 以前本地服务的方式
*/
/*class MyBinder extends Binder implements ISinger { *//**
* 通过ID查询歌手姓名
*
* @param id
* @return
*//*
@Override
public String querySingerNameByID(int id) {
String result = null;
switch (id) {
case 1:
result = "黄家驹";
break;
case 2:
result = "王杰";
break;
case 3:
result = "陈百强";
break;
default:
result = "张雨生";
break;
}
return result;
}
}*/ /**
* AIDL的方式,只有这种方式才能完成远程服务
*/
class MyBinderAidl extends IMusician.Stub { @Override
public String querySingerNameByID(int id) throws RemoteException {
String result = null;
int result2 = 0;
switch (id) {
case 1:
result = "黄家驹";
result2 = 210000;
break;
case 2:
result = "王杰";
result2 = 180000;
break;
case 3:
result = "陈百强";
result2 = 200000;
break;
default:
result = "张雨生";
result2 = 200090;
break;
}
return result;
}
}
}

Service2,以前本地服务接口的定义:

package liudeli.service2.service.inter;

import java.lang.String;

public interface ISinger {

    /**
* 通过ID查询歌手姓名
* @param id
* @return
*/
public String querySingerNameByID(int id); }

Service2,现在远程服务的AIdl语言接口的定义:

// IMusician.aidl
package liudeli.service2; // Declare any non-default types here with import statements interface IMusician { /**
* 通过ID查询歌手姓名
* @param id
* @return
*/
String querySingerNameByID(int id);
}

----------------------------- 分割线 下面代码是 Service1 访问者相关的了

Service1,⚠️要把Service2 aidl 带包一起copy到Service1,保持aidl相关一模一样

Service1,绑定远程服务相关代码

package liudeli.service1;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.widget.Toast; import liudeli.service2.IMusician; public class RemoteActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_remote); bindServiceAction();
} /**
* Activity初始化的时候绑定服务
*/
private void bindServiceAction() {
Intent intent = new Intent();
intent.setAction("liudeli.service2.service.MyService");
// android 5.0以后直设置action不能启动相应的服务,需要设置packageName或者Component
intent.setPackage("liudeli.service2");
bindService(intent, connection, BIND_AUTO_CREATE);
} private IMusician iMusician; /**
* 定义服务连接对象,用于连接远程服务
*/
private ServiceConnection connection = new ServiceConnection() {
/**
* 服务连接成功
* @param name 可以获取到服务到完整信息
* @param service 服务那边返回到IBinder接口
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 这里和本地服务不同,本地服务是强制类型转换,远程服务直接使用代理完成
iMusician = IMusician.Stub.asInterface(service);
} /**
* 服务断开连接
* @param name
*/
@Override
public void onServiceDisconnected(ComponentName name) { }
}; /**
* 查询远程服务里面的数据
* @param view
*/
public void queryRemoteService(View view) {
if (null == iMusician) {
Toast.makeText(this, "绑定远程服务失败,无法查询", Toast.LENGTH_LONG).show();
return;
}
try {
String result = iMusician.querySingerNameByID(1);
Toast.makeText(this, "查询成功:" + result, Toast.LENGTH_LONG).show();
} catch (RemoteException e) {
e.printStackTrace();
Toast.makeText(this, "远程服务失败 远程异常", Toast.LENGTH_LONG).show();
}
} /**
* Activity结束时,记得一定要解绑服务,否则会报连接资源异常
*/
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(connection);
}
}

Layout相关代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"> <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="queryRemoteService"
android:text="查询远程服务"
/> </LinearLayout>

结果:

Android-bindService远程服务(Aidl)-初步的更多相关文章

  1. Android 中的AIDL,Parcelable和远程服务

    Android 中的AIDL,Parcelable和远程服务      早期在学习期间便接触到AIDL,当时对此的运用也是一撇而过.只到近日在项目中接触到AIDL,才开始仔细深入.AIDL的作用    ...

  2. Android:学习AIDL,这一篇文章就够了(下)

    前言 上一篇博文介绍了关于AIDL是什么,为什么我们需要AIDL,AIDL的语法以及如何使用AIDL等方面的知识,这一篇博文将顺着上一篇的思路往下走,接着介绍关于AIDL的一些更加深入的知识.强烈建议 ...

  3. (转载)Android:学习AIDL,这一篇文章就够了(下)

    前言 上一篇博文介绍了关于AIDL是什么,为什么我们需要AIDL,AIDL的语法以及如何使用AIDL等方面的知识,这一篇博文将顺着上一篇的思路往下走,接着介绍关于AIDL的一些更加深入的知识.强烈建议 ...

  4. (转载)Android:学习AIDL,这一篇文章就够了(上)

    前言 在决定用这个标题之前甚是忐忑,主要是担心自己对AIDL的理解不够深入,到时候大家看了之后说——你这是什么玩意儿,就这么点东西就敢说够了?简直是坐井观天不知所谓——那样就很尴尬了.不过又转念一想, ...

  5. 【转载】Android Studio Service AIDL 详解

    公司产品之前IM这块存在很多问题,消息到达率低,加上协议上有些问题,丢消息频繁,所以需要重构IM,AIDL不能解决以上问题.好吧!那AIDL可以解决什么问题?什么是AIDL? 什么是AIDL? AID ...

  6. android studio 使用 aidl(二)异步回调

    基础使用请移步 android studio 使用 aidl (一) 首先建立在server端建立两个aidl文件 ITaskCallback.aidl 用于存放要回调client端的方法 // IT ...

  7. android studio 使用 aidl(一)基础用法

    最近公司需要开发一个项目用的到aidl,之前研究过eclipse版本的,但是好久了一直没用,现在需要捡起来,但是现在都用android studio了,所以查了下资料 都不是很全,我在这里总结一下,方 ...

  8. Android bindservice使用

    package com.example.myact10; import com.example.myact10.MyService.MyBinder; import android.support.v ...

  9. Android service binder aidl 关系

    /********************************************************************************** * Android servic ...

随机推荐

  1. 证件照制作:使用PS打印一寸照片

    1. 打开文件,文件-打开-选择要操作的图片: 2. 修改图片尺寸,图像-图像大小,弹出对话框后,设置 宽度:2.5cm,高度:3.5cm,分辨率:300 像素/英寸: 3. 为要打印的照片设置白边, ...

  2. django之上传图片

    上传图片 当Django在处理文件上传的时候,文件数据被保存在request.FILES FILES中的每个键为<input type="file" name="& ...

  3. mongodb分片(七)

    1.插入负载技术分片架构图 2.片键的概念和用处 看下面这个普通的集合和分片后的结果 3.什么时候用到分片呢? 3.1机器的磁盘空间不足 3.2单个的mongoDB服务器已经不能满足大量的插入操作 3 ...

  4. Hexo+Github/Coding免费搭建个人博客网站

    体验更优排版请移步原文:http://blog.kwin.wang/other/hexo-github-build-blog.html 很早之前就想搭建一个属于自己的博客网站,一方面是给自己做笔记,把 ...

  5. 跟我学算法-tensorflow 实现神经网络

    神经网络主要是存在一个前向传播的过程,我们的目的也是使得代价函数值最小化 采用的数据是minist数据,训练集为50000*28*28 测试集为10000*28*28 lable 为50000*10, ...

  6. 关于Remoting的个人使用心得

    最经几天比较闲写了一个基于Tcp网络通信的聊天程序,写的过程中实现了文件传输,可是却怎样也无法将文件名传送过去,期间想过用通信的端口发送文件的名称,但是又要自己定义一个协议,觉得那样比较麻烦,于是想到 ...

  7. Java中Final修饰一个变量时,是引用不能变还是引用的对象不能变

    Java中,使用Final修饰一个变量,是引用不能变,还是引用对象不能变? 是引用对象的地址不能变,引用变量所指的对象的内容可以改变. final变量永远指向这个对象,是一个常量指针,而不是指向常量的 ...

  8. 201671010127 2016-2017-11 Java图形用户界面设计技术

    一.事件处理器 1.什么是事件处理 一个事件要求特定的动作被执行,它被作为消息由外界或系统自身发送给GUI系统.这些事件包括来自计算机设备如鼠标键盘和网络端口的I/O中断,以及GUI系统的逻辑事件触发 ...

  9. 微信小程序相关三、css写小黄人

    小程序上课第三天,因为今天院里有活动,所以没去上课,第四天上午又因为要召开入党转正大会,又耽误了一上午,下午去上课,要了资料.这两天讲了一些零零碎碎的东西,做的实例有上面这个小黄人 都是用的css,基 ...

  10. 微信小程序相关二、css介绍,菜单制作,表单相关,京东注册页面

    一.第二天上午 1.1上午因为有其他的课所以没有去这个课,不过下午看复习的时候的概括,讲了DTD,语法特性,css选择器以及权重,还有一些简单的样式 1.2 DTD Docuement Type 声明 ...