接着我们来看下JNI的编译过程和调用流程,给出如下图:(具体见分享的JNI书籍,这个是windows上的一个图,里面的helloworld.dll在linux体系会变成helloworld.so)
执行过程:
本地代码编译生成helloworld.so动态库,在java类增加
static {
System.loadLibrary("HelloWorld");
} ,这样在此类使用时,首先会将此动态库加载到此进程的系统空间里面,具体应用 查看linux 里面 的 dlopen dlsym 函数。
之后,我们调用java类里面的用native 声明的函数,系统会自动去从动态库去查找,没有找到,则会异常。
5.2.3 apk配置以及JNI编写:
因为要设置时间,如果使用apk方式实现,那么我们看到/dev/alarm 设备是需要system权限的,因此我们需要配置 android:sharedUserId="android.uid.system"
和使用system签名生成apk,才能获得system uid
关键步骤:(详细的去本讲内容里面查找)
AndroidManifest.xml 里面:
Android.mk 配置为:
配置签名为系统platform,如此便具有系统uid,随后验证。
JNI java端代码:
cmd在src目录使用javah -classpath . -jni com.example.systemtime.JNI 生成com_example_systemtime_JNI.h
复制com_example_systemtime_JNI.h到jni目录,配置jni目录下的android.mk
配置为动态库。
配置com_example_systemtime_JNI.c 实现com_example_systemtime_JNI.h里面的函数即可。
将此文件夹放到package/apps/systemtime
使用./mk mm package/apps/systemtime编译,我们平台是将系统apk里面的so提取出来了,放置在system/lib下面,因此我们测试需要eng版本,如果我们使用eclipse开发,默认是会将so保存在apk里面的。
完成后使用eng版本,
adb install -r (+apk文件路径)
adb remount
adb push (+ libtimetest.so 路径 ) system/lib
启动apk点击ok,可以看到时间已被修改,ps查看进程看到
system 3024 144 310688 28208 ffffffff 400f624c S com.example.systemtime
Userid 变为syste m 了