安卓之JNI 和 NDK编程(五)java调用c++代码详细介绍

文章目录

1、新建Jni类

动态库名字的来源

gradle简单介绍

2、native-lib.cpp的c++代码

3、MainActivity类


1、新建Jni类

package com.luminal.ndktest;

/**
 * 用来封装Jni的native接口的
 */
public class Jni {

    //因为有很多地方要调用到,所以写成单例
    private static Jni obj = new Jni();
    public static Jni instance() {
        return obj;
    }

    //加载动态库
    static {
        //动态库的名字,参见"CMakeLists.txt"文件
        System.loadLibrary("native-lib");
    }


    //写一个native方法getStringFromJni,
    //那么我们在c++代码里面要写一个对应的方法
    public native String getStringFromJni();


}

动态库名字的来源

动态库的名字,参见"CMakeLists.txt"文件,如下图:

gradle简单介绍

当我们运行项目的时候,它有这个gradle会自动编译动态库。

gradle 类似于java编译脚本,编译的时候会根据配置文件进行编译,如:根据配置文件build.gradle(Module:app)

用C++来写NDK非常麻烦,如果你只改变C++的代码,不改变java的代码,它不会重新加载这个动态库!

非常的头痛,那么使用cmake之后,就不会出现这种问题,它会根据依赖关系自动编译代码。

2、native-lib.cpp的c++代码

#include <jni.h>
#include <string>

//************** 与java的Jni类中getStringFromJni方法所对应的方法 **************
//1、方法名的定义,前面已经介绍(上篇文章)。

//2、返回值类型
//getStringFromJni方法返回的是String类型,此c++方法对应返回的是jstring类型。
//jstring是c++中定义的类型,用来映射java类型,相当于java的String字符串类型。
//如:jobject相当于java的Object对象类型

//3、参数类型
//java中的getStringFromJni方法没有定义参数类型,
//但jni规范规定要多添加两个参数:JNIEnv* env, jobject obj
//env表示java虚拟机对象。因为java的代码是运行在虚拟机上的,所以env可以理解为java虚拟机。
//obj表示调用该方法的java对象。
//该方法指的是:Java_com_luminal_ndktest_Jni_stringFromJNI 方法
//这个java对象指的是Jni类对象,Jni类是一个单例对象,也就指的是定义的那个obj对象
//参见上面“1、新建Jni类”

//为什么需要 extern "C" ???
//它能够保证c++编译此方法的时候,不会对这个方法进行变名,
//如果没有的话,c++编译器会把此方法变名,那么变成别的名字java就找不到了
//所以使用 extern "C" ,来保证方法名不变,java虚拟机才能找到这个方法
extern "C"  jstring Java_com_luminal_ndktest_Jni_getStringFromJni(JNIEnv* env, jobject obj){

    return env->NewStringUTF("Test xxx");

}




3、MainActivity类

package com.luminal.ndktest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity {

    //动态库加载一次就行了,在Jni类里面已经加载!多次加载会出问题
    // Used to load the 'native-lib' library on application startup.
//    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());


        String str = Jni.instance().getStringFromJni();
        TextView tv = (TextView) findViewById(R.id.sample_text);
        tv.setText(str);
        Log.v("MainActivityTag",str);

    }

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

}

最终效果如下:

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

被开发耽误的大厨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值