-
难点
- HAL重写
- JNI 使用
- 子主题 3
- 子主题 4
-
JNI学习
-
Java代码部分
- static{
System.loadLibrary("hello-jni");
}
表示 libhello-jni.so 这个库会在第一次使用HelloJni这个类的时候加载
- public native String stringFromJNI();
public native String unimplementedStringFromJNI();
native方法表示这两个方法是本地方法
-
C/C++代码部分
-
编写.h头文件
-
自动生成
- 已经生成class的基础上
- 工程目录下建立一个jni文件夹
- javah -classpath bin/classes/ -d jni com.example.hellojni.HelloJni
- -classpath bin:表示类的路径, 这里bin/classes/里包含编译好的class文件
- -d jni: 表示生成的头文件存放的目录
- com.example.hellojni.HelloJni 则是完整类名
-
手动书写
- JNI头文件分析
- JNI头文件的组成
- 生成的头文件
- 头文件 jni.h
- 注释部分
- Class
- 具有此本地方法的类的名称
- Method
- 本地方法的名称
- Signature
- 方法的标识
- 本地方法在头文件中的表示
- eg:JNIEXPORT jobject JNICALL Java_HeaderTest_doObject (JNIEnv *, jobject, jobject);
- 分析
- JNIEXPORT <JNIType> JNICALL Java_HeaderTest_doVoid (JNIEnv *, jobject);
1 2 3 4 5 6 7
- 1. JNIEXPORT(1)和JNICALL(3)都是JNI的关键字,表示此函数是要被JNI调用的。
- 2. <JNIType>(2)为本地方法返回的数据类型,对应与java源文件中的该方法返回的数据类型
- 3. Java(4)为JNI中标识此方法来源于java的标识头
- 4. _HeaderTest(5)表示该方法所在的类
- 5. _doVoid(6)为JNI中对应与java文件中本地方法的方法名。这不是完全对应的哦!重载方法是一个例外!
- 6. (JNIEnv *, jobject)(7)方法的最后一部分哦!比较复杂,它们有一个共同的特点,包含JNIEnv *――它是一个接口指针,用于定位函数表中的函数!
在JNI规范中一般称为“Interface Pointer”。看到这儿好像和过程调用很类似了!是的,JNI中的操作过程,就是面向过程的!
后面的jobject是一个指向该类的指针,类似与C语言中的this。这个第二个参数是变化的,当该方法为类的实例方法时该参数为jobject;
当该方法为类方法(即静态方法)时该参数为jclass,指向该类的class
- java的数据类型和JNI中数据类型的映射
- 1) java中的返回值void和JNI中的void是完全对应的哦!(仅仅一个而已)。
2) java中的基本数据类型(byte ,short ,int,long,float,double ,boolean,char-8种)在JNI中对应的数据类型只要在前面加上j就对应了(jbyte ,jshort ,jint,jlong,jfloat,jdouble ,jboolean,jchar)。
3) java中的对象,包括类库中定义的类、接口以及自定义的类接口,都对应于JNI中的jobject。
4) java中基本数据类型的数组对应与JNI中的j<type>array类型。(type就是上面说的8种基本数据类型)
5) java中对象的数组对应于JNI中的jobjectArray类型。(在java中一切对象、接口以及数组都是对象)
- Topic
- Topic
- 重载方法的区别
- 重载方法时,方法的后面还有一个表示方法参数的“后缀”。
例如上面操作的变量为Int时加一个表示此类型的标识“I”;
多个类型当然依次加多个了;当某个变量为数组时在其类型前面会加一个“3”;
当其为对象时后面会加一个“L”表示这是一个对象,以及一个该对象的路径,不过路径之间用“_”代替包路径的“.”或者文件路径的“/”哦!
参数为对象时对象名称后还要加上“2”,表示该参数为一个对象
- 实例方法和静态方法的区别
- 在本地实例方法中该参数为jobject,代表对象本身,在本地静态方法中该参数为jclass
-
Android.mk文件
-
LOCAL_PATH := $(call my-dir)
- 一个Android.mk 文件首先必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件。在这个例子中,宏函数’my-dir’, 由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)。
- include $( CLEAR_VARS)
- LOCAL_MODULE := hello-jni
- LOCAL_SRC_FILES := hello-jni.c
-
include $(BUILD_SHARED_LIBRARY)
- 子主题 1
- 子主题 6
-
System用户组
- Android.mk文件中增加 LOCAL_CERTIFICATE := platform
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.settings"
android:sharedUserId="android.uid.system">