AndroidStudio 使用AIDL
http://blog.csdn.net/ducklikejava/article/details/51559244
Android Studio
中写的一个AIDL
的小DEMO.- 步骤很繁琐,本来不准备写的。但是写一下是为了记录,这一下午终于跑通了这玩意。
- 首先,你要有3个
Module
,至少两个,但是最好是3个- 一个是你的
AIDL
文件与它的Service
所在的Module
- 一个是你的客户端
Module
,也就是你真正调用AIDL
的Module
- 最后一个是你的
AIDL
需要使用的Parcelable
对象存放的Module
.如果你要传递的只是基本的数据类型,那么这一项可以不要。如果你直接将该对象创建在你的调用AIDL
的Module
中,这一项也可以不要。 - 为什么我说要3个
Module
呢?- 因为:第三个
Module
是作为第一个和第二个的共同依赖存在的。这样,两边都可以使用其中的 对象。
- 因为:第三个
- 一个是你的
然后,你得先有一个
Service
,这个Service
就是你的AIDL
的具体实现。你的AIDL
想要什么功能,完全取决于你的service
怎么写了。package com.pythoncat.aidl_libiary; import android.app.Service;
import android.content.Intent; public class HelloService extends Service {
public HelloService() {
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 好了,你的
Service
已经有了。但是目前还没有什么意义。为了将这个AIDL
做得有意思一点,我们假设你是要通过AIDL
传递复杂的数据,比如Student
这样类似的一个java bean
。 - 既然这样,那么,我们就需要一个
Student
类了,注意:必须实现Parcelable
,不如就不能AIDL
了。差不多这个类就长这样:
package com.pythoncat.core.model;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by pythonCat on 2016/6/1.
*/
public class Student implements Parcelable {
public String name;
public int age;
public int sex;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.name);
dest.writeInt(this.age);
dest.writeInt(this.sex);
}
public Student() {
}
protected Student(Parcel in) {
this.name = in.readString();
this.age = in.readInt();
this.sex = in.readInt();
}
public static final Creator<Student> CREATOR = new Creator<Student>() {
@Override
public Student createFromParcel(Parcel source) {
return new Student(source);
}
@Override
public Student[] newArray(int size) {
return new Student[size];
}
};
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 好了,你的
Student
已经准备好了,现在就是真的要定义一下AIDL
文件了。因为这个Student
是要通过AIDL
去传递的,所以这个Student
也要成为一个AIDL
.
这句话听起来比较费解,是因为我表达的不够好。其实说白了,就是要多创建一个名为
Student.aidl
的文件,这个文件差不多这样:
// Student.aidl
package com.pythoncat.core.model;
parcelable Student;
- 1
- 2
- 3
- 1
- 2
- 3
注意了:这个文件所在目录,必须是在一个
aidl
目录下,创建一个和Student.Java
同包名的包。比如,我的Student.java
是在package com.pythoncat.core.model;
中,那么,我就要在AIDL
所在Module
中,创建一个aidl
目录,然后在该目录下创建一个package
,package
名字就是package com.pythoncat.core.model
。最后,在该package
下,创建一个Student.aidl
文件,里面就写上面3句话就好了。
到这里,
Javabean
算是真的准备好了,显示开始写你的需要被外界调用的AIDL
了。这个文件位置随便写,你就在java
目录下创建一个.aidl
文件好了。文件名假设是IHelloInterface
,文件假设是这样的:
```
// IHelloInterface.aidl
package com.pythoncat.aidl_libiary;
import com.pythoncat.core.model.Student;
// Declare any non-default types here with import statements
interface IHelloInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
String hello();
Student getOne();
}
```
注意一下,上面有一个
import com.pythoncat.core.model.Student;
就是刚才的那个Student.aidl
的导入。、
- ok,到了这里。已经完成了一小半了。然后是,
build -> make project (ctrl+F9)
一下。让android studio
帮你一把。 build -> make project (ctrl+F9)
之后,你会看到你的IHelloInterface .aidl
自动跑到aidl
目录里面去了。不过这个都不是我关心的。现在,我们完善我们的
HelloService
:package com.pythoncat.aidl_libiary; import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable; import com.pythoncat.core.model.Student; /**
* <action android:name="com.pythoncat.aidl_libiary.HelloService"/>
* <hr/>
* package="com.pythoncat.aidl_libiary"
*/
public class HelloService extends Service {
public HelloService() {
} @Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
} class MyBinder extends IHelloInterface.Stub { @Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } @Override
public String hello() throws RemoteException {
return "Just Hello World";
} @Override
public Student getOne() throws RemoteException {
return new Student();
}
}
}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 发现没有,现在我们的
Service,AIDL,Model
已经关联起来了,接下来就是调用者的事情了。 - ** 既然是调用者的事情了,那我们就搞一个
Activity
去调用试试吧。 - 在调用处,其实和平常的绑定服务几乎没有任何的差别,都是通过
ServiceConnection
去获取接口的引用,然后就可以调用接口里面的方法了。[接口的实现,已经在我们的HelloService
里面搞定了]。 调用就一个
Activity
里面一个按钮的点击事件 ,布局文件就不写了,没什么意义。那么调用者差不多这样的:package com.pythoncat.helloaidl; import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.view.View; import com.apkfuns.logutils.LogUtils;
import com.github.johnpersano.supertoasts.SuperToast;
import com.pythoncat.aidl_libiary.IHelloInterface;
import com.pythoncat.core.model.Student; public class MainActivity extends AppCompatActivity { private IHelloInterface iService;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iService = IHelloInterface.Stub.asInterface(service);
try {
final String hello = iService.hello();
LogUtils.e("hello::::::::" + hello);
final Student one = iService.getOne();
LogUtils.e(one);
runOnUiThread(new Runnable() {
@Override
public void run() {
SuperToast.cancelAllSuperToasts();
SuperToast.create(getApplicationContext(), hello, SuperToast.Duration.MEDIUM).show();
}
});
} catch (RemoteException e) {
e.printStackTrace();
}
} @Override
public void onServiceDisconnected(ComponentName name) {
iService = null;
LogUtils.e("iService::::::::" + iService);
}
};
private boolean bindService; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); } @Override
protected void onStart() {
super.onStart();
final Intent in = new Intent();
in.setClassName(this, "com.pythoncat.aidl_libiary.HelloService");
in.setPackage("com.pythoncat.aidl_libiary");
in.setAction("com.pythoncat.aidl_libiary.HelloService");
bindService = bindService(in, conn, Context.BIND_AUTO_CREATE);
LogUtils.e("bindService=" + bindService);
} @Override
protected void onStop() {
super.onStop();
if (conn != null) {
unbindService(conn);
}
} public void clickButton(View v) {
LogUtils.e("bindService=" + bindService);
LogUtils.e(iService);
if (iService == null) {
SuperToast.cancelAllSuperToasts();
SuperToast.create(getApplicationContext(), iService + "", SuperToast.Duration.MEDIUM).show();
} else {
SuperToast.cancelAllSuperToasts();
try {
SuperToast.create(getApplicationContext(), iService.hello(), SuperToast.Duration.MEDIUM).show();
} catch (RemoteException e) {
e.printStackTrace();
}
} }
}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 这样,其实就已经完成了一个
AIDL
的调用的整个过程。 - 另外,一旦项目跑不通,多弄几次
build -> make project (ctrl+F9)
的操作,还是跑不通,就是代码有问题了。
不过,我必须坦白的是,我的调用者的
Module
还是引用了AIDL
所在Module
。因为我不引用就不能成功绑定远程服务。这个问题应该是可以解决的,以后解决了,再记录到这边来。 - 项目戳我,戳我啊~…~
- 真的彩蛋后续更新FINAL
AndroidStudio 使用AIDL的更多相关文章
- AndroidStudio实现AIDL
AIDL的使用步骤 aidl远程调用传递的参数和返回值支持Java的基本类型(int long booen char byte等)和String,List,Map等.当然也支持一个自定义对象的传递. ...
- Android-Service基本用法、AIDL、Binder连接池详解
本文介绍Service与Activity之间的通信,文章包含以下内容: 一.Service基本用法 二.通过AIDL实现Service与Activity跨进程通信 三.Binder连接池 四.使用Me ...
- Android IPC机制之AIDL
什么是AIDL AIDL:Android Interface Definition Language,即Android接口定义语言. Android系统中的进程之间不能共享内存,因此,需要提供一些机制 ...
- [转]AndroidStudio导出jar包
原文链接:http://blog.csdn.net/hjq842382134/article/details/38538097# 1. 不像在Eclipse,可以直接导出jar包.AndroidStu ...
- [Android Pro] AndroidStudio导出jar包
reference : http://blog.csdn.net/beijingshi1/article/details/38681281 不像在Eclipse,可以直接导出jar包.Android ...
- 一起简单写一下AIDL,入个门
前话 最近接触了Android开发的一个新知识,AIDL(¬_¬因为到现在都没用过) 因此不断谷歌找资料找Demo,自己尝试写一下. 因为用AndroidStudio作为开发环境,期间遇到过许多问题, ...
- Android的IPC机制(一)——AIDL的使用
综述 IPC(interprocess communication)是指进程间通信,也就是在两个进程间进行数据交互.不同的操作系统都有他们自己的一套IPC机制.例如在Linux操作系统中可以通过管道. ...
- AIDL进程间调用与Binder的简单介绍
Binder是安卓中特有的一种进程间通信(IPC)方式,从Unix发展而来的手段,通信双方必须处理线程同步.内存管理等复杂问题,传统的Socket.匿名通道(Pipe).匿名管道(FIFO).信号量( ...
- AndroidStudio学习记录
AndroidStudio学习记录 1. 插件的使用. plugins.jetbrains.com插件网站. 2. 目录介绍: 1.Studio中有Project和Module的概念,前面说到Stud ...
随机推荐
- 第六篇:二维数组的传输 (host <-> device)
前言 本文的目的很明确:介绍如何将二维数组传递进显存,以及如何将二维数组从显存传递回主机端. 实现步骤 1. 在显存中为二维数组开辟空间 2. 获取该二维数组在显存中的 pitch 值 (cudaMa ...
- 2D绘图引擎比较
这个问题很普遍.最近在研究这个问题,在网上搜了一些资料,再结合自己的经验,谈谈自己的一些想法. 一.双缓存能提高绘图效率吗? 网上有篇文章:绘图效率完整解决方案——三种手段提高GDI/GDI+绘图效率 ...
- c++ const(不断跟新)
1.把一个 const 对象的地址赋给一个普通的.非 const 对象的指针也会导致编译时的错误: const double pi = 3.14; double *ptr = π // error: ...
- 『SharePoint 2010』Sharepoint 2010 Form 身份认证的实现(基于AD)
一.进管理中心,创建一个应用程序,配置如下: 二.填端口号,和选择form身份认证,以及填写成员和角色,其他都默认就可以了 三.使用SharePoint 2010 Management Shell在里 ...
- Python全栈day21-22-23(模块)
一,python的模块 Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块让你能够有逻辑地组织你的 Python ...
- Web浏览器导出FTP服务器上的文件
开发思路:1.代码登录ftp服务器下载文件到服务器2.通过web浏览器下载服务器上的文件 using System; using System.Collections; using System.Co ...
- Python多股票同周期可视化
import warnings warnings.filterwarnings("ignore") import numpy as np import pandas as pd i ...
- 一篇搞定MongoDB
MongoDB最基础的东西,我这边就不多说了,这提供罗兄三篇给大家热身 MongoDB初始 MongoDB逻辑与物理存储结构 MongoDB的基础操作 最后对上述内容和关系型数据做个对比 非关系型数据 ...
- HDFS集群安装
DFS集群安装: 1.准备工作 (1)虚拟机(电脑8G 磁盘500GB) (2)3台linux系统(1台namenode 2台datanode) 2.安装HDFS(软件) (1)关闭防火墙 firew ...
- python常见模块之序列化(json与pickle以及shelve)
什么是序列化? 我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flatte ...