【安卓】JNI一般开发流程

1.新建一个java类并声明public native方法:

1.0 注意C语言和java的衔接:

Java的文件名必须是Java类名
C/C++的.c文件名是完全自定义的,.h文件和头文件名就是头文件名
看多了Java的朋友再回来看C/C++别搞混了。

1.1:Java文件

  • new Java Project
  • new Package:注意包名不要下划线
  • new class
  • 在新建的Java class中声明public native方法:
    如:
public native String getMyStringFromJNI();

1.2:C语言编译器:实现Java方法对应的C方法(方法在头文件中)

  • 在cmd下cd 到当前java类所在的src文件夹下
  • 使用javah -jni命令+包名+类名 生成java类对应的c的头文件:
    然后刷新Refresh即可。

注意:头文件包含C/C++的方法的声明,再在.c文件中实现其方法体即可。

1.3:返回到java类中:

  • 在新建的Java class中加载动态库:即C/C++头文件
static {
		//加载当前目录下的C++头文件
        System.loadLibrary("native-lib");//native-lib就是C++的头文件名
    }

	//其中:可以用System.load("文件具体路径")的形式加载。
  • 然后调用getMyStringFromJNI()方法就相当于调用对应的C语言的头文件中的用javah -jni生成的头文件中对应的方法。

2.总结:

其实JNI的实现逻辑并不复杂:
1.Java方法:要有一个函数名,并且有一个static加载动态库(即C的头文件)的声明。
2.C方法:C函数的函数名要包含在头文件中,函数的实现在.c文件中,所以要实现一个对应的头文件,还有一个C函数名。
3.然后最终实现的就是Java函数名,C/C++实现的效果。

注意:这些函数名和头文件理论上应该具有标准命名格式的。

3.Android Studio中使用JNI开发:

在Android Studio中使用JNI开发会更方便,Android Studio会自动帮你实现很多步骤,只要你在新建项目的时候,选择模板native C++即可。

下面粘贴Android Studio下的jni代码示例:

(1)Java代码层:

文件名(即类名):
MainActivity

package com.example.mynative;
import ...
public class MainActivity extends AppCompatActivity {

    // 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 = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI()+"\n"+stringFromJNI1());
    }

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

(1)C++代码层:

文件名(即头文件名):
native-lib

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

extern "C"//采用C的编译模式,不允许函数重载,保证函数名唯一,即Java函数名和C/C++函数名一一对应。
JNIEXPORT jstring JNICALL//两关键字,1.允许方法可以外部调用,2.表示jni可以调用。

//参数1:C和Java互相调用的中介,使用env->即可显示其中的函数。所以此处可以实现C中调用Java属性和方法等。
//参数2:C函数对应的java函数所在对象,这里就是this
Java_com_example_mynative_MainActivity_stringFromJNI(JNIEnv* env,jobject j/* this */) {
    std::string hello = "Hello from C++ by JNI";
    return env->NewStringUTF(hello.c_str());
}

extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_mynative_MainActivity_stringFromJNI1(JNIEnv *env, jobject thiz) {
    // TODO: implement stringFromJNI1()
    std::string hello = "第二个函数返回的:Hello from C++ by JNI";
    return env->NewStringUTF(hello.c_str());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值