Android Studio 2.2下AIDL完全配置解析入手。
来源:互联网 发布:集团军总司令源码程序 编辑:程序博客网 时间:2024/05/16 19:41
前言
模拟:我们需要外部进程服务提供一个计算地点横纵坐标的方法来显示到我们自己的Textview上。
步骤
第一步创建相对应Aidl文件与需要自定义的类型
创建自定义类型
首先新建一个项目
这里我们需要定义一个自定义类型LocationData 为了记录横众坐标与服务Pid,创建!
LocationData.java 实现ParceLable借口,代码注释挺明白。具体可另行百度。
public class LocationData implements Parcelable { int width;//代表横 int heigth;//代表纵 public LocationData(){ } public LocationData(Parcel in){ readFromParcel(in);//对象通过Binder从Parcel返回拿到 } @Override public int describeContents() { return 0;//描绘类型信息一般不用管 } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(width);//数据写入容器Parcel dest.writeInt(heigth); } public static final Creator<LocationData> CREATOR = new Creator<LocationData>() { //内部类实现对象反序列化 @Override public LocationData createFromParcel(Parcel in) { return new LocationData(in); } @Override public LocationData[] newArray(int size) { return new LocationData[size]; } }; /** 从Parcel中读取数据 **/ public void readFromParcel(Parcel in){ width = in.readInt(); heigth = in.readInt(); } public int getHeigth() { return heigth; } public void setHeigth(int heigth) { this.heigth = heigth; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } @Override public String toString() { return "width = "+ width + ", heigth="+ heigth; }}
自定义类型LocationData.aidl文件很简单无需过多声明只要声明出类型即可。
AS2.2创建Aidl文件
LocationData.aidl
package com.ljs.testfitsystem;parcelable LocationData;
默认Aidl支持原生类型只支持如下,所以需要我们自定义类型。
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString);
为什么自定义类型需要从新定义adil呢,可见如下blog。
http://blog.csdn.net/luojiusan520/article/details/52862202
声明创建aidl接口
- 创建AIDL接口,提供接口IMyAidlInterface.aidl;
// IMyAidlInterface.aidlpackage com.ljs.aidltest;import com.ljs.aidltest.LocationData;// 导入自定义类型// Declare any non-default types here with import statementsinterface IMyAidlInterface { int getPid();//获得当前服务进程ID LocationData getMyData();//提供LocationData对象给予我们Client}
这里我们最初的文件准备得到如下
最后再编译项目,
得到我们接口文件。内部含1个内部类stub。stub内部含有Proxy类。具体就是对Binder的一些控制与数据操作,由于此文件自动生成,我们也不需要过多关心。
编写RPC中的远程服务,
创建RemoteService.java 继承service,
这里我们为了模拟跨进程通信使用 android:process=“”来替代生成一个IPC通信的远程服务。
<service android:name=".RemoteService" android:process=":server"> //随意设置只是一个进程名称 <intent-filter> <action android:name="com.ljs.adiltest"></action>//用来启动服务 </intent-filter> </service>
具体service文件如下已经作注释:
public class RemoteService extends Service { private static final String TAG = "server"; //Log观察生命周期 LocationData mMyData; @Override public void onCreate() { super.onCreate(); Log.i(TAG, "[server] onCreate"); initMyData();//初始化Location } @Override public IBinder onBind(Intent intent) { Log.i(TAG,"[server] onBind"); return mBinder; } @Override public boolean onUnbind(Intent intent) { Log.i(TAG, "[server] onUnbind"); return super.onUnbind(intent); } @Override public void onDestroy() { Log.i(TAG, "[server] onDestroy"); super.onDestroy(); } //通过Aidl生成文件中Stub类实现我们生成接口中的方法 IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() { @Override public int getPid() throws RemoteException { Log.i(TAG,"[server] getPid()="+android.os.Process.myPid()); return android.os.Process.myPid(); } @Override public LocationData getMyData() throws RemoteException { Log.i(TAG,"[server] getMyData() "+ mMyData.toString()); return mMyData; } //Binder驱动底层调用传送数据,由于server ,1对多,一般不设置也可以做权限设置,判断是否需要传递速度给Client。 @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { return super.onTransact(code, data, reply, flags); } }; /** * 初始化MyData数据 **/ private void initMyData() { mMyData = new LocationData(); mMyData.setWidth((int)(Math.random()*100));//随机给予位置信息 mMyData.setHeigth((int)(Math.random()*100)); }}
客户端编写
得到接口,服务端准备好,我们客户端Bind服务就可以进行IPC通信了。
client编写
MainActivity.java 重要部分已经注释
public class MainActivity extends AppCompatActivity { private static final String TAG = "Client"; private IMyAidlInterface mRemoteService; private boolean mIsBound =false;//是否已经绑定 private TextView mTv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(TAG, "[Client] onCreate"); setContentView(R.layout.activity_main); mTv = (TextView) findViewById(R.id.tv); mTv.setText("还未连接"); } //监控远程服务状态链接,ServiceConnection private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mRemoteService = IMyAidlInterface.Stub.asInterface(service);//链接上了才会调用 String pidInfo = null; try { LocationData myData = mRemoteService.getMyData(); pidInfo ="客户端Pid"+ Process.myPid()+ "服务Pid="+ mRemoteService.getPid() + ", 横坐标 = "+ myData.getWidth() + ", 纵坐标="+ myData.getHeigth(); } catch (RemoteException e) { e.printStackTrace(); } Log.i(TAG, "[Client] onServiceConnected "+pidInfo); mTv.setText(pidInfo); Toast.makeText(MainActivity.this, "绑定上了哦", Toast.LENGTH_SHORT).show(); } @Override public void onServiceDisconnected(ComponentName name) { //正常顺序默认不调用意外情况销毁调用 Log.i(TAG, "[Client] onServiceDisconnected"); mTv.setText("服务与客户端断开"); mRemoteService = null; Toast.makeText(MainActivity.this, "已经断开服务", Toast.LENGTH_SHORT).show(); } }; public void clickButton(View view){ switch (view.getId()){ case R.id.btn_bind: bindRemoteService(); break; case R.id.btn_unbind: unbindRemoteService(); break; case R.id.btn_kill: killRemoteService(); break; } }//绑定远程服务 private void bindRemoteService(){ Log.i(TAG, "[Client] bindRemoteService"); Intent intent = new Intent(MainActivity.this, RemoteService.class); intent.setAction("com.ljs.adiltestAction"); intent.setPackage(getPackageName());//Android5.0不允许直接隐式启动,需要加包名 bindService(intent, mConnection, Context.BIND_AUTO_CREATE); mIsBound = true; mTv.setText("开始绑定服务"); } //解除绑定 private void unbindRemoteService(){ Log.i(TAG, "[Client] unbindRemoteService ==>"); if(!mIsBound){ Toast.makeText(MainActivity.this, "不需要解绑已经没有绑定服务", Toast.LENGTH_SHORT).show(); return; } unbindService(mConnection); mIsBound = false; mTv.setText("解除绑定服务"); } //kill远程服务 private void killRemoteService(){ Log.i(TAG, "[Client] killRemoteService"); try { android.os.Process.killProcess(mRemoteService.getPid()); mTv.setText("Kill掉远程服务所在进程"); Toast.makeText(MainActivity.this, "远程服务杀掉了哦", Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "服务进程不存在,杀死服务进程失败", Toast.LENGTH_SHORT).show(); } }}
程序Bind服务调用服务方法接口获得服务端随机算出来的LocationData对象与服务进程Pid截图
依次执行生成Log信息
Client下顺序 2570-2570/com.ljs.aidltest I/Client: [Client] onCreate 2570-2570/com.ljs.aidltest I/Client: [Client] bindRemoteService 2570-2570/com.ljs.aidltest I/Client: [Client] onServiceConnected 客户端Pid2570服务Pid=3579, 横坐标 = 31, 纵坐标=8 2570-2570/com.ljs.aidltest I/Client: [Client] unbindRemoteService ==> 2570-2570/com.ljs.aidltest I/Client: [Client] killRemoteServiceserver下顺序3579-3579/com.ljs.aidltest:Remoteserver I/Server: [server] onCreate3579-3579/com.ljs.aidltest:Remoteserver I/Server: [server] onBind3579-3592/com.ljs.aidltest:Remoteserver I/Server: [server] getMyData() width = 31, heigth=83579-3591/com.ljs.aidltest:Remoteserver I/Server: [server] getPid()=3579 3579-3579/com.ljs.aidltest:Remoteserver I/Server: [server] onUnbind3579-3579/com.ljs.aidltest:Remoteserver I/Server: [server] onDestroy
Github具体源代码地址
https://github.com/anderson9/AIDLnewDemo
0 0
- Android Studio 2.2下AIDL完全配置解析入手。
- Android Studio下如何配置AIDL文件
- Android studio下AIDL操作
- Android Studio下使用aidl
- android studio下aidl编程
- 10.1 Android Studio入手
- ubuntu15.04下Android studio开发配置完全教程
- Android Studio下简单编译AIDL方法
- android studio下aidl的使用
- Android Studio下AIDL的使用方法
- android studio下的aidl通信
- Android studio 1.2开发环境下配置AIDL,生成相应的.java文件
- Android Studio下如何配置AIDL文件并生成java文件
- Android Studio 2.2新增布局——ConstraintLayout完全解析
- Android ActionBar完全解析(下)
- Android ActionBar完全解析(下)
- Android Service完全解析 (下)
- Android studio import aidl
- 【Linux】centOS 启动流程图
- 如何在 CentOS / RHEL 上设置 SSH 免密码登录
- 什么是编译性语言、解释性语言和脚本语言
- VC++ 创建进程并等待其退出
- Qt: 基于QTcpSocket的聊天程序
- Android Studio 2.2下AIDL完全配置解析入手。
- rails 练习9 --整理文章列表上的连接
- mysql表空间
- Apache之Cannot load modules/mod_access_compat.so into server
- 用PCA(主成分分析法)进行信号滤波
- Java中Synchronized的用法
- 关于django migrations的使用
- Cocoapods踩坑记录
- 关于OpenOCD+ST-LINK的若干问题