代码在评论中。
JNI:
为什么需要JNI:
因为android是由【JAVA & C/C++】组成。Java运行在Dalvik虚拟机中。
没有办法直接访问底层硬件。底层HW相关目前技术一般都用C语言,不会用java,C速度也比较快。
怎么从JAVA语言传送数据到C语言中:
1. java中会调用native标识的函数,这个函数就是经典了。
2.当然这些native的函数怎么调用,就得加载一个提供C函数包,叫共享库(ex:libNewJNI.so)
3.问题来了,这.so文件怎么来的? 从一下两个文件编译后产生的(.h & .c/cpp),当然Android.mk中设置编译选项楼。
4.完成了,很简单吧。
AIDL:
为什么需要AIDL:
AIDL机制就是处理客户端和服务端的通信,通过AIDL机制,客户端通过调用服务端提供的接口便于跨进程调用其他应用程序.
Service分为本地服务和远程服务,远程服务就一定要用到AIDL技术实现,因为android的不同应用是在不同的进程中运行的,
也是彼此独立的,如果在一个应用中访问另一个应用,也就是调用远程服务,就要把服务端定义的AIDL文件放到客户端,
这样才可以实现远程服务调用。
怎么从一个进程调动另一个进程:
1.首先AIDL代码是?
很简单,后缀名仅仅是.aidl,内容就是interface class。
2.怎么用AIDL?
也简单,就是编译后aidl文件就变成了,*.java文件
打开文件看的话,你又明白了,是一个Binder
static abstract class Stub extends android.os.Binder implements android.com.personservice.IPerson
3.客户端怎么调用这个Stub(调用server传来的数据)
private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName arg0) { } // 因为有可能有多个应用同时进行RPC操作,所以同步该方法 @Override public synchronized void onServiceConnected(ComponentName arg0, IBinder binder) { // 获得IPerson接口 person = IPerson.Stub.asInterface(binder); if (person != null) { try { // RPC方法调用 String name = person.getName(); Toast.makeText(MainActivity.this, "远程进程调用成功!值为 : " + name, Toast.LENGTH_LONG).show(); } catch (RemoteException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "远程进程调用失败! ", Toast.LENGTH_LONG).show(); } } } };
4.服务端和客户端都必须有相同名字aidl文件吗?
当然,客户端包含的interface比服务端少是可以的,
因为服务端是提供interface的,所以必须包含客户端请求的interface。
5.服务端比客户端多的是什么?
1) AIDL中的interface 函数
2) 实现类,实现aidl生成的抽象类(aidl编译生成的java)
3) 还有一个service类。
6.服务端怎么赋值给客户端?
private ServiceConnection conn = new ServiceConnection() { // 断开连接时调用 @Override public void onServiceDisconnected(ComponentName arg0) { } // 连接时调用 @Override public void onServiceConnected(ComponentName arg0, IBinder binder) { iPerson = IPerson.Stub.asInterface(binder); if (iPerson != null) { try { iPerson.setName("My name is 'Server AIDL'"); Toast.makeText(MainActivity.this, "赋值成功!", Toast.LENGTH_LONG).show(); } catch (RemoteException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "赋值失败!", Toast.LENGTH_LONG).show(); } } } };
7.这些IPerson的实现是什么?
与一般的实现抽象类一样。
public class PersonImpl extends IPerson.Stub { private String name; @Override public String getName() throws RemoteException { return name; } @Override public void setName(String name) throws RemoteException { this.name = name; } }
8. service是?
直接return那个实现类
public class MyService extends Service { private Stub iPerson = new PersonImpl(); @Override public IBinder onBind(Intent arg0) { Log.i("service", "onBind..."); return iPerson; } }