Android Studio开发JNIproject

使用Android Sutdio创建一个新的project后,接下来记录创建NDKproject的基本步骤。

本文将达到:
1. 创建NDKproject
2. 在JNI中输出Log语句
3. 指定编译的so库的abi版本号
4. 解决在创建NDKproject中的问题

Step: 1. 加入native接口
注意写好native接口和System.loadLibrary()就可以了。并无特别之处。
P.S:onCreate()中对R.id.txt运行setText()。所以这里须要对xml布局文件按正常的开发步骤进行改动就可以。

直接给出代码例如以下:
public class MainActivity extends Activity{
    static {
        System.loadLibrary("JniTest");
    }
   
    public native String getStringFromNative();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView txtView = (TextView) findViewById(R.id.txt);
        txtView.setText(getStringFromNative());
    }
}



Step: 2.运行Build->Make Project


这一步骤运行一下,验证project中并无其他错误,并对project进行了编译,生成了.class文件.
.class文件的生成路径是在 app_path/build/intermediates/classes/debug下的.例如以下图:


Step: 3.javah生成c头文件

点击"View->Tool Windows->Terminal",即在Studio中进行终端命令行工具.运行例如以下命令生成c语言头文件。
这里须要注意的是要进入 <Project>appsrcmain的文件夹下运行javah命令,为的是生成的 .h 文件相同是在<Project>appsrcmain路径下,能够在Studio的project结构中直接看到。


操作命令:
javah -d jni -classpath <SDK_android.jar>;<APP_classes> lab.sodino.jnitest.MainActivity
详细操作图例如以下:

javah -d jni -classpath c:UserssodinochenAppDataLocalAndroidsdkplatforms
android-16android.jar;....uildintermediatesclassesdebug lab.sodino.jnitest.MainActivity


对于"主版本号51比50新,此编译器支持最新的主版本号"则是因为电脑上安装了两个版本号的jdk引起的,而当前使用的是旧的jdk。
把旧的jdk删除。并运行java version命令后显示当前jdk为最新的1.7时,则不会再有此提示了。例如以下图:

最后的生成结果:




Step: 4.编辑c文件

在main.c文件里实现头文件里的方法,详细功能为直接return回一个String。而且使用android_log打印出相关日志。

代码例如以下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <android/log.h>

#ifndef LOG_TAG
#define LOG_TAG "ANDROID_LAB"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#endif

/* Header for class lab_sodino_jnitest_MainActivity */

#ifndef _Included_lab_sodino_jnitest_MainActivity
#define _Included_lab_sodino_jnitest_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class: lab_sodino_jnitest_MainActivity
 * Method: getStringFromNative
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_lab_sodino_jnitest_MainActivity_getStringFromNative
  (JNIEnv * env, jobject jObj){
      LOGE("log string from ndk.");
      return (*env)->NewStringUTF(env,"Hello From JNI!");
  }

#ifdef __cplusplus
}
#endif
#endif

到这里后。我们再运行一个"Build->Make Project"。发现"Messages Gradle Build"会给出提演示样例如以下:
Error:Execution failed for task ':app:compileDebugNdk'. 
> NDK not configured. 
Download the NDK from http://developer.android.com/tools/sdk/ndk/.Then add ndk.dir=path/to/ndk in local.properties. 
(On Windows, make sure you escape backslashes, e.g. C:\ndk rather than C:
dk)
这里提示了NDK未配置,而且须要在project中的local.properties文件里配置NDK路径。

好了,提示非常清楚了。那我们就进入下一步吧。



Step: 5.配置NDK
这一步包含两个动作:
1.指明ndk路径

2. 改动build.gradle配置
    project中共同拥有两个build.gradle配置文件。我们要改动的是在<Project>appuild.gradle这个文件。为其在defaultConfig分支中添加上
    ndk {
        moduleName "JniTest"
        ldLibs "log", "z", "m"
        abiFilters "armeabi", "armeabi-v7a", "x86"
    }
    以上配置代码指定的so库名称为JniTest,链接时使用到的库。相应android.mk文件里的LOCAL_LDLIBS。及终于输出指定三种abi体系结构下的so库。
加入后例如以下图:

这时,再运行"Build->Rebuild Project",就能够编译出so文件了。
但在Window平台上会出现一个问题:
Error:Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.internal.LoggedErrorException: Failed to run command:
 D:Missionadt-bundle-windows
dk-r10b
dk-build.cmd NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates
dkdebugAndroid.mk APP_PLATFORM=android-21 NDK_OUT=C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates
dkdebugobj NDK_LIBS_OUT=C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates
dkdebuglib APP_ABI=armeabi,armeabi-v7a,x86
Error Code:
 2
Output:
 make.exe: *** No rule to make target `C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates
dkdebugobj/local/armeabi/objs/JniTest/C_UserssodinochenAndroidstudioProjectsJniTest2appsrcmainjni', needed by `C:UserssodinochenAndroidstudioProjectsJniTest2appuildintermediates
dkdebugobj/local/armeabi/objs/JniTest/C_UserssodinochenAndroidstudioProjectsJniTest2appsrcmainjnimain.o'. Stop.
出现这个错误非常莫名其妙..几番折腾下,找到一个视频出来了大概原因及解决方案:
出处见Youtube视频 02:50分開始:https://www.youtube.com/watch?

v=okLKfxfbz40#t=362

在Windows下NDK一个bug,当只编译一个文件时出现会出现此问题,解决方法就是再往jni文件夹加入一个空util.c文件就可以。例如以下图:


编译出来的库文件被Studio输出到了下图的路径中




Step: 6.安装运行

界面:


查看Log打印:


原文地址:https://www.cnblogs.com/mfrbuaa/p/5371507.html