android 7.0 静态注册,JNI方法的静态注册和动态注册RegisterNatives

代码结构如下:

Android下的Java代码 仍然还是使用了eclipse开发环境 这里在NDKUtils.java文件里定义了所有的本地方法

0818b9ca8b590ca3270a3433284dd417.png

Linux下的C代码 这里是在Linux系统目录下新建的文件 其中libs/和obj/都是由ndk-build编译后编译器产生

0818b9ca8b590ca3270a3433284dd417.png

// MainActivity.java

public class MainActivity extends Activity implements View.OnClickListener {

private Button btnJni1, btnJni2, btnJni3;

private TextView tvShowInfo;

private NDKUtils jniUtil;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

init();

}

private void init() {

jniUtil = new NDKUtils();

btnJni1 = (Button) findViewById(R.id.btnJni1);

btnJni1.setOnClickListener(this);

btnJni2 = (Button) findViewById(R.id.btnJni2);

btnJni2.setOnClickListener(this);

btnJni3 = (Button) findViewById(R.id.btnJni3);

btnJni3.setOnClickListener(this);

tvShowInfo = (TextView) findViewById(R.id.tvShowInfo);

}

@Override

public void onClick(View view) {

switch (view.getId()) {

case R.id.btnJni1:

tvShowInfo.setText(String.format("【静态调用Jni】获取String,输出为:\n %s", jniUtil.getVipString()));

break;

case R.id.btnJni2:

tvShowInfo.setText(String.format("【静态调用Jni】输入vip,加密输出为:\n %s", jniUtil.staticGenerateKey("vip")));

break;

case R.id.btnJni3:

tvShowInfo.setText(String.format("【动态调用Jni】输入test,加密输出为:\n %s", jniUtil.dynamicGenerateKey("test")));

break;

default:

break;

}

}

}

// NDKUtils.java

public class NDKUtils {

static {

System.loadLibrary("zzyJni");

}

public native String getVipString();

public native String staticGenerateKey(String name);

public native String dynamicGenerateKey(String name);

}

这次的编译没有使用windows下的工具Cygwin64

而是直接在Linux系统下使用ndk-build工具生成对应的动态库(/libs/armeabi/libzzyJni.so)

直接使用ndk-build脚本编译出动态库也是非常简单的 在Linux宿主机上不需要安装和配置

只需要把android-ndk-r14b-linux-x86_64.zip解压到机器上 通过export导入路径到系统配置下就能直接使用

操作方法:

1 下载Linux版本的android-ndk-r14b-linux-x86_64.zip (我的Linux设备为Ubuntu64位操作系统)

2 导入ndk目录到系统配置,这里我使用了仅为我当前登录的用户有效

3 到/JniDemo-master/jni/目录下直接执行ndk-build脚本生成libs/和obj/目录以及动态库

4 拷贝动态库libzzyJni.so到eclipse对应的/libs/armeabi/libzzyJni.so

5 编译安卓应用程序到手机

0818b9ca8b590ca3270a3433284dd417.png

NDK脚本的导入方法:

android-ndk-r14b-linux-x86_64/目录下执行两条export导入命令

/android-ndk-r14b$ export ANDROID_NDK=/home/admin/tools/android-ndk-r14b

/android-ndk-r14b$ export PATH=$PATH:$ANDROID_NDK

在/JniDemo-master目录下执行ndk-build脚本生成obj/和libs/libzzyJni.so动态库

/JniDemo-master$ ndk-build

还在使用古老的eclipse 是因为已经有一段时间没有做安卓项目 所以没有使用Android studio

如果使用AS开发的话 就不需要手动编写 Android.mk 等编译的脚本文件

这里关于编译脚本中指定使用哪种架构的CPU还做了区分armeabi或者armeabi-v7a 或者其他类型

在Application.mk中可以看到我已经指定编译的CPU类型为 armeabi

APP_PLATFORM = android-23

APP_ABI := armeabi

APP_STL := stlport_static

APP_OPTIM := debug

就做个简单介绍

Android 设备的CPU类型(通常称为”ABIs”)

armeabiv-v7a: 第7代及以上的 ARM 处理器。2011年15月以后的生产的大部分Android设备都使用它.

arm64-v8a: 第8代、64位ARM处理器,很少设备,三星 Galaxy S6是其中之一。

armeabi: 第5代、第6代的ARM处理器,早期的手机用的比较多。

x86: 平板、模拟器用得比较多。

x86_64: 64位的平板。

最后关于查看库中存在哪些函数方法:

使用nm命令失败的话 nm: no symbols

可以使用

$ objdump -tT libxsfJni.so

运行在JM虚拟机上的Java代码是怎么样找到对应的本地方法的

这里有两种方法可以找到

1 C/C++代码的函数名以包名加上函数声明的形式让Java代码找到 属于静态方式

2 C/C++通过JNIEnv中的RegisterNatives方法注册函数名 属于动态方式

动态注册方式:

static JNINativeMethod methods[] = {

{"dynamicGenerateKey", "(Ljava/lang/String;)Ljava/lang/String;", (void *) native_dynamic_key},

};

static int registerNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *gMethods, int numMethods) {

jclass clazz;

clazz = (*env)->FindClass(env, className);

if (clazz == NULL) {

return JNI_FALSE;

}

if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) { return JNI_FALSE; } return JNI_TRUE; } static int registerNatives(JNIEnv *env) { const char *className = "demo/jnidemo/NDKUtils"; //指定注册的类 return registerNativeMethods(env, className, methods, sizeof(methods) / sizeof(methods[0])); } JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){ JNIEnv* env = NULL; jint result = -1; if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) { return -1; } assert(env != NULL); if (!registerNatives(env)){ return -1; } return JNI_VERSION_1_4; }

JNI_OnLoad函数作为JNI加载的入口,直接在这里进行函数的动态注册

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值