android studio搭建JNI开发环境

1.明确为何要学习JNI

  • JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他编程语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的。例如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少要保证本地代码能工作在任何Java 虚拟机环境。
  • Java开发要用到JDK,Android开发要用到SDK,那我们在Android中要进行native开发,也要用到它对应的工具包,即NDK。通俗的来讲,NDK就是帮助我们可以在Android应用中使用C/C++来完成特定功能的一套工具。 NDK的作用有很多,我们简单的列举两个,比如:
    1.首先NDK可以帮助开发者“快速”开发C(或C++)的动态库。
    2.其次,NDK集成了“交叉编译器”。使用NDK,我们可以将要求高性能的应用逻辑使用C开发,从而提高应用程序的执行效率.
    arm结构 :主要在移动手持、嵌入式设备上。我们的手机几乎都是使用的这种CUP架构。
    x86结构 : 主要在台式机、笔记本上使用。如Intel和AMD的CPU 。
    MIPS架构:多用在网关、猫、机顶盒等设备

2.NDK下载:https://developer.android.google.cn/ndk/downloads 根据操作系统选择

3.as配置ndk:file->Project Structure->SDK Location->Android NdK Location写入下载解压后的ndk路径

4.jni开发流程

  1. 在MainActivity类中声明函数jniSay(native关键字):
public class MainActivity extends AppCompatActivity {

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

   }

   public native String jniSay(String str);

   public void click(View view) {
       System.loadLibrary("JniSay");
       String str=jniSay("hello word");
       Toast.makeText(this,str,Toast.LENGTH_LONG).show();
   }
}
  1. 在main目录下新建文件夹jni
  2. 在jni下新建JniSay.c文件
  3. 进到main/java里使用命令:
D:\android\jniTest\app\src\main\java>javah -jni com.zcx.myapplication.MainActivity
  1. 打开生成的com_zcx_myapplication_MainActivity.h文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_zcx_myapplication_MainActivity */

#ifndef _Included_com_zcx_myapplication_MainActivity
#define _Included_com_zcx_myapplication_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     com_zcx_myapplication_MainActivity
* Method:    jniSay
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_zcx_myapplication_MainActivity_jniSay
 (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif
  1. 将下述代码复制到JniSay.c文件里
#include<stdlib.h>
#include<jni.h>

JNIEXPORT jstring JNICALL Java_com_zcx_myapplication_MainActivity_jniSay(JNIEnv * env,jstring str){
   char* c="I am from c....";
   return (**env).NewStringUTF(env,c);
}

jstring对应java中的string类
jstring本质还是void*类型的指针(在jni.h里申明的所以要导入)
7. 在jni目录下新建Android.mk (https://developer.android.google.cn/ndk/guides/android_mk)

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE:= JniSay
LOCAL_SRC_FILES:= JniSay.c
#LOCAL_CFLAGS:= -Wall -Wextra -Werror
#LOCAL_EXPORT_C_INCLUDES:= $(LOCAL_PATH)
#LOCAL_EXPORT_LDLIBS:= -ldl
include $(BUILD_SHARED_LIBRARY)
  1. 在jni目录下新建Application.mk (https://developer.android.google.cn/ndk/guides/application_mk)可选
  2. 进入jni目录执行命令:ndk-build JniSay
  3. 在项目gradle.properties里添加: android.useDeprecatedNdk=true
  4. 在app/build.gradle里的defaultConfig节点添加:
defaultConfig {
        applicationId "com.zcx.myapplication"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        ndk {
            moduleName "JniSay"
            abiFilters "armeabi", "armeabi-v7a", "x86"
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    sourceSets {
        main {
            jniLibs.srcDir 'libs'
        }
    }
  1. 将main/obj/local下的文件复制到 项目/libs下
发布了46 篇原创文章 · 获赞 90 · 访问量 33万+

猜你喜欢

转载自blog.csdn.net/qq_40077167/article/details/89245563