你的位置:首页 > 操作系统

[操作系统]说明一下JNI 与AIDL


代码在评论中。

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;  }}