开始学习JNI开发一

 

android开发5年了,老实说,前几年都是在混日子,技术基本原地踏步毫无长进,近一年半突然开窍了,长江后浪拍前浪,安于现状的程序员死在沙滩上,所以基本上从基础上,把以前自己怕的,不想去看的都列计划看了一大部分,JNI也是一个门槛吧,想到看到就头疼,不行逼着自己搞。C语言大学学了,但是自己基本完全没记住学了什么,花了2个月时间看了基础,指针,总算大体不复杂的代码能看懂了,学C也有一个好处,底层的种种原理对于上层来说都是通用的,以前不理解的现在能稍微理解了.好吧废话不多说,直接进入主题,JNI开发第一篇:android调JNI和JNI调android基本用法。后续会有一系列,随着学习继续更新。

工具android studio 3.2.1 创建JNI程序直接看到最后,用默认的下面两个看自己的选择了,应用过后会生成带有JNI开发的android工程

 android studio3.2.1中有一个非常好的功能点,引入JNI之后会把android源码中的一些库文件全部展示给你,这样在之后设计到对android底层库的调用的时候不需要再自己翻源码找头文件什么的了,这点非常赞啊。

 工程自带一个DEMO例子,会显示来自JNI的一断文字,这个等于就是应用层调JNI的基础展示了

static {
    System.loadLibrary("native-lib");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Example of a call to a native method
    TextView tv = (TextView) findViewById(R.id.sample_text);
    tv.setText(stringFromJNI());

//    CallMethod();
  //  CallStaticMethod();
}

public void test1(String a){
    Toast.makeText(getApplicationContext(),a,1).show();
}
public static void test2(){
    Log.d("debug","这是来自JNI的消息");
}

/**
 * A native method that is implemented by the 'native-lib' native library,
 * which is packaged with this application.
 */
public native String stringFromJNI();

 我们来分析下基本的调用流程,先加载动态库文件,这个其实做android的应该都不陌生就是各种SO文件,然后有一个方法

public native String stringFromJNI() 这个就是要调我们JNI中执行的方法了,必须要用native,没有函数的实现。再来看JNI层的代码

 extern "c" 是表示支持C语言。 后面的一串我们看中间的白色修饰,表示这个函数的返回值类型是jstring,什么是jstring?jni封装了自己的数据结构 jstring jobject jint等等,对应java的基本数据类型,string和引用对象,不知道的这个可以自行查看很简单。

我们继续看函数名称,很长一大串啊我滴妈,看着就头疼,其实不用怕,这个都算固定格式的,可以通过javah命令自动生成,在AS3.2.1 中更方便,写好native体,按照提示就可以一键生成了。Java开头,跟包名类名方法名,中间用_隔开即可非常简单,就是看着吓人

里面的具体内容就比较简单了,JNIEnv指正 调用方法创建一个Jstring 对象返回个JAVA层,Jstring 对应java中的string对象。通过JNI返回给JAVA的内容,都要转成JNI的数据结构再返回

基本调用就是这样,是不是非常简单。漫过了心里的一个坎了就,接下来说JNI调用JAVA。如果对JAVA反射很熟的话,下面的内容你会觉得更加容易 Come on

我在MainActivity中创建了两个变量,一个静态,一个非静态,通过JNI修改它们的值

 

 MainActivity写好方法体

构建JNI中的方法

 

方法声明我们就跳过不说了,我们看看里面具体的操作。JNI跳JAVA非常想反射

方法体里面有两个参数JNIEnv jobject,前一个是JNI的环境指针,后一个代表JAVA调用的当前对象,

JNI通过调用的对象获取到class的对象,JNI中jclass,通过jclass可以获得class中的很多属性,比如方法,属性等等。JNI调用的基本流程都是一样的,拿到class,先获取方法或者属性的ID,然后通过这个ID来拿到设置属性或者调用方法。

我们来说说具体的调用

GetrFieldID/GetMethodID传入jclass 第二个参数属性/方法的名称,第三个参数是属性/方法的签名。签名是JNI中的调用的重点,可以简单点的说是,用在属性上描述的是属性的类型,用在方法上面面试方法的参数类型和返回值类型,通过这个再结合名称就可以找到唯一的方法或者变量ID。具体签名对照下表。

拿到ID之后就好办了,属性通过getObjectField传入对象引用 属性ID就可以获得这个对象的值了,可以在这上面进行操作啦。当然属性有静态的,可以通过getStaticField传入class和属性ID来操作

方法的话拿到ID,可以通过Call<type>method()来进行操作,type表示的是返回值的类型

基本互相调用流程就是这样,很简单,没有我以前想的那么可怕,凡是还是要上手才行

代码https://github.com/loulousky/StartJni 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值