靠谱Android Studio JNI Demo
Posted Androider_Zxg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了靠谱Android Studio JNI Demo相关的知识,希望对你有一定的参考价值。
前言
作为工作了近四年时间的android开发,搞通这个Demo用了一个工作日,觉得自己动手能力有些差,所以记录下。这里我们不介绍JNI的基础理论知识。只讲Demo流程。
Demo
第一步
创建Demo工程,从SDK Manager中下载NDK相关组件,同时将Support Repository也下载下来
第二步
创建Java文件,如下:
package com.example.jnidemo;
public class JNITest
public native String getStrFromJNI();
第三步
使用javah命令生成JNITest的头文件。我就是这步卡主的,在使用javah命令过程中遇到了很多问题。例如 javah不是命令、无法识别的文件名、找不到类文件。这里我说下我这里如何跑通的。注意以下几点。
-
1、在Android Studio的终端中使用Javah如果报不是内部或外部命令,也不是可运行的程序。则在cmd命令行中执行,只要环境变量配置无误,一定会识别javah命令
-
2、在生成的classes文件夹目录下使用命令,在源文件目录下执行会报找不到xxx的类文件
-
3、之前class文件目录是在build/intermediates/classes/debug下。我一度怀疑没有生成class文件。后来发现目录是:build/intermediates/javac/debug/complieDebugJavaWithJavac/classes下。那么我们就在如下目录下执行如下命令:
javah -jni com.example.jnidemo.JNITest
如下:
生成的.h文件就在同目录下,如下:
第四步
在src/main/下建立jni文件下,jni文件夹与java文件是平行的。建立方法如下:
第五步
将刚刚生成的.h文件复制到jni目录下,并编写其实现类,文件名自取,我们这里就叫demo.c。如下:
//
// Created by xxx on 2019/6/17.
//
#include<jni.h>
//导入头文件
#include "com_example_jnidemo_JNITest.h"
//实现.h文件中定义的方法
jstring Java_com_example_jnidemo_JNITest_getStrFromJNI(JNIEnv *env,jobject thiz)
return (*env)->NewStringUTF(env,"I am Str from jni libs!");
第六步
在jni文件夹下建立Android.mk文件用于编译,如下:
#my-dir:返回当前 Android.mk 所在的目录的路径
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# 定义生成so文件的名字
LOCAL_MODULE := hello-jni
# 需要编译的文件,由于在一个文件夹下,不用写路径
LOCAL_SRC_FILES := demo.c
include $(BUILD_SHARED_LIBRARY)
# 指定生成全部的ABI的so文件
APP_ABI := all
第七步
在app.gradle中android内添加ndk相关配置,如下:
externalNativeBuild
ndkBuild
path 'src/main/jni/Android.mk'
第八步
make project即可看到生成的so文件,如下:
可以看到每个ABI均生成了so文件,但是so文件的名字多了个前缀lib,这是因为Android强制要求所有的so文件必须是lib前缀,我们可以看到例如高德地图、融云聊天等第三方的so库也是如此
第九步
加载so文件并使用,如下:
package com.example.jnidemo;
public class JNITest
static
System.loadLibrary("jni-demo");//与Android.mk文件中设置的一致,不需要手动添加前缀lib
public native String getStrFromJNI();
package com.example.jnidemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new JNITest();
((TextView)findViewById(R.id.tv_info)).setText(new JNITest().getStrFromJNI());
文件目录
写在后边
这里只介绍了最基础最简单的jni使用方法,还有如CMake等方式没有调研。后边有时间会陆续更新。如照着这个Demo跑不通可留言共同探讨。网上还有另一种方式,不写Android.mk文件,而是在app.gradle的defaultConfig下添加ndk设置,如下:
ndk
moduleName "NdkJniDemo" //生成的so名字
abiFilters "armeabi-v7a", "x86","arm64-v8a","x86_64" //输出指定三种abi体系结构下的so库,目前可有可无。
我并没有跑通。没有继续纠结。
以上是关于靠谱Android Studio JNI Demo的主要内容,如果未能解决你的问题,请参考以下文章