让JNI告诉你 你的应用为什么被卸载(1)

二  实例演示


首先我们要明白的是,为什么有些项目中要使用C,原因很简单,哪怕是一个计算,C的效率也要高于Java,Java做的C可以做,Java不可以做的C也可以做,所以有些复杂的处理操作或者是底层相关的逻辑都可以交给C去做,像美图秀秀,播放器等软件都用了大量的C代码处理业务。

  • 2.1 Java调用C代码,以验证用户名密码为例

验证用户名密码我们肯定要将用户名和密码传给C,我们新建一个JNI类,在类中新建一个返回整形的方法,如下所示。

public native int checkUser(String name, String pass);

记得使用关键字native,这个时候我们就要在C中编写相应的方法,像什么,javah生成头文件什么的那种我在前言中说了,就不讲解了,在studio工具中生成,鼠标点击到方法,Alt + Enter快捷方式自动生成如下方法

#include <jni.h>

JNIEXPORT jint JNICALL

Java_jnidemo_hlq_com_jnidemo_JNI_checkUser(JNIEnv *env, jobject instance, jstring name_,

jstring pass_) {

const char *name = (env)->GetStringUTFChars(name_, 0);

const char *pass = (env)->GetStringUTFChars(pass_, 0);

// TODO

(env)->ReleaseStringUTFChars( name_, name);

(env)->ReleaseStringUTFChars( pass_, pass);

}

在这里要注意一下,这里我们建的是.cpp文件,至于.c 和 .cpp 就是一个是c一个是c++

c++中代码是

const char *name = (env)->GetStringUTFChars(name_, 0);

c中对应的就是

const char *name = (*env)->GetStringUTFChars(env,name_, 0);

接下来我们要在cmake中进行配置

add_library( # Sets the name of the library.

checkuser

SHARED

src/main/cpp/cheruser.cpp

)

checkuser 就是配置生成的so名称为libcheckuser.so,SHARED配置库文件是共享, src/main/cpp/cheruser.cpp就是对应的路径了

target_link_libraries( # Specifies the target library.

checkuser

Links the target library to the log library

included in the NDK.

${log-lib} )

checkuser保持和上面名字对应就可以了。

这样我们就可以在JNI类中,加载这个库

static {

System.loadLibrary(“checkuser”);

}

在C代码中我们已经得到了name和pass

const char *name = (env)->GetStringUTFChars(name_, 0);

const char *pass = (env)->GetStringUTFChars(pass_, 0);

直接和用户名密码比较即可,这里在代码中将变量名定义为name 密码为123

const char *tureName = “name”;

const char *turePass = “123”;

使用strcmp函数来比较,两个字符串相等则返回0,记得引用string.h头文件

#include <string.h>

if (strcmp(name,tureName) == 0 && strcasecmp(pass,turePass) == 0){

return 1;

} else{

return 0;

}

我们在Activity中输入用户名密码,调用C方法,若返回1则说明登陆成功,若返回0则说明用户名密码不正确,登陆失败

if (new JNI().checkUser(“name”, “123”) == 1) {

Toast.makeText(MainActivity.this, “登陆成功”, Toast.LENGTH_LONG).show();

} else {

Toast.makeText(MainActivity.this, “登陆shibai”, Toast.LENGTH_LONG).show();

}

2.2 c语言调用Java方法

首先我们在JNI类中新建一个sum方法,返回两数之和

public int sum(int i, int j) {

Log.d(“—”, “我是java 我被c调用了” + (i + j));

return i + j;

}

C调用Java肯定要Java调用C的某个方法,在这个方法中调用java方法,所以我们再来新建一个testHello方法

public native String testHello();

默认生成的C方法为

JNIEXPORT jstring JNICALL

Java_jnidemo_hlq_com_jnidemo_JNI_testHello(JNIEnv *env, jobject) {

return (env)->NewStringUTF(“huanglinqing”);

}

我们要调用的java方法在JNI类中,想想java可以通过反射来调用另一个类的方法,那么C其实也是通过反射的,首先我们定义要调用方法的路径,JNI类全路径为jnidemo.hlq.com.jnidemo.JNI,在C中将.替换为/

const char *className = “jnidemo/hlq/com/jnidemo/JNI”;

方法名为sum

const char *sum = “sum”;

通过findClass获取class对象,然后通过AllocObject获取类的实例

jclass jclass1 = env->FindClass(className);

jobject jobject1 = env->AllocObject(jclass1);

然后我们获取到要调用方法的methodId

jmethodID jmethodID1 = env->GetMethodID(jclass1, sum,“(II)I”);

第一个参数是class对象,第二个参数是函数名,第三个参数是方法签名

复制项目app\build\intermediates\classes\debug文件路径,打开cmd,进入路径,(如果之前没有编译过项目记得先编译一下,这样才能获取class文件),使用命令 javap -s jnidemo.hlq.com.jnidemo.JNI jnidemo.hlq.com.jnidemo.JNI是调用方法的全路径。

运行可以看到sum方法的签名是(II)I

获取到方法的jmethodID1之后调用CallIntMethod即可调用方法

jint value = env->CallIntMethod(jobject1, jmethodID1,1,2);

第一个参数是类的实例,第二个参数是获取的jmethodID1,后面就是sum函数依次对应的参数。

代码整体为:

const char *className = “jnidemo/hlq/com/jnidemo/JNI”;

const char *sum = “sum”;

jclass jclass1 = env->FindClass(className);

jmethodID jmethodID1 = env->GetMethodID(jclass1, sum,“(II)I”);

jobject jobject1 = env->AllocObject(jclass1);

jint value = env->CallIntMethod(jobject1, jmethodID1,1,2);

printf(“c 运行结果为 %d”,value);

我们在activity中调用

new JNI().testHello();

分享读者

作者2013年java转到Android开发,在小厂待过,也去过华为,OPPO等大厂待过,18年四月份进了阿里一直到现在。

被人面试过,也面试过很多人。深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长,而且极易碰到天花板技术停滞不前!

我们整理了一份阿里P7级别的Android架构师全套学习资料,特别适合有3-5年以上经验的小伙伴深入学习提升。

主要包括阿里,以及字节跳动,腾讯,华为,小米,等一线互联网公司主流架构技术。如果你有需要,尽管拿走好了。

35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

被人面试过,也面试过很多人。深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长,而且极易碰到天花板技术停滞不前!

我们整理了一份阿里P7级别的Android架构师全套学习资料,特别适合有3-5年以上经验的小伙伴深入学习提升。

主要包括阿里,以及字节跳动,腾讯,华为,小米,等一线互联网公司主流架构技术。如果你有需要,尽管拿走好了。

[外链图片转存中…(img-jyhFk7wS-1715392774873)]

35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值