说明一下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;
    }

}

 

posted on 2016-01-28 11:04  金洪光  阅读(4814)  评论(1编辑  收藏  举报

导航