Android(安卓)Studio 新建一个简单的Jni-demo,实现了so库的生成与调用(使用 javah 和 ndk-build指令方式来生成so库)。
三步走
第一步:创建一个Jni-demo项目。以图形方式一步步指引(just for 新手):
等待gradle build的完成,第一步就此结束。
备注:如果有的朋友遇到gradle太慢的情况,可以参考我的这篇博文,希望可以解决你的问题。https://blog.csdn.net/qq_41811438/article/details/97616483
第二步:生成so库。
1、添加jni文件。
如此操作后,在<项目存放位置>\app\src\main目录下就多出了一个jni空文件夹。
比如我的就是在E:\AndroidProjects\JNI_Test\Jni-demo\app\src\main下多了一个jni空文件夹。
2、创建一个java类,在其中定义native方式。
如此操作后,会在MainActivity.java所在位置,新建一个名为Java_Interface.java的文件。
附上Java_Interface.java的源码:(简单实现一个加法和返回一个String)
package research.exam.com.jni_demo;/** * Created by Administrator on 2019/8/5. */public class Java_Interface { static { System.loadLibrary("jniTest"); } //functions declaration: public native String GetHellString(); public native int Add(int n1, int n2);}
3、由Java_Interface.java生成jni头文件。
备注:有关下图所示的NDK配置,请参考我的这个博客,希望可以帮助到你。https://blog.csdn.net/qq_41811438/article/details/97616166
此时在我的项目的app/src/main/jni目录下就多了一个jni头文件,如下图所示:
4、在jni头文件所在目录添加三个文件,用来生成so库用的。它们是Android.mk Application.mk JNI.cpp三个文件。
附上相关源码,仅供参考学习。
Android.mk 文件源码如下所示:
LOCAL_PATH := $(call my-dir) #获取Android.mk所在目录include $(CLEAR_VARS)# 下面一句是用来指定so库生成位置的,感兴趣的朋友可以试试,确实可以改变so库生成位置。# NDK_APP_DST_DIR=../../../../../SharedLibs/$(TARGET_ARCH_ABI)LOCAL_MODULE := jniTest #指定生成so库的名称LOCAL_SRC_FILES := JNI.cpp #指定生成so库所需源码文件include $(BUILD_SHARED_LIBRARY) #说明生成的是动态so库(这句是废话)
Application.mk 文件源码如下所示:
# APP_ABI :=armeabi armeabi-v7a mips x86APP_ABI :=armeabi-v7a #指定生成的so库适用的cpu架构,这个是最常见的一种。
JNI.cpp文件源码如下所示:
#include"research_exam_com_jni_demo_Java_Interface.h"JNIEXPORT jstring JNICALL Java_research_exam_com_jni_1demo_Java_1Interface_GetHellString(JNIEnv *env, jobject obj){ return env->NewStringUTF("I love C++ Programming in Android.");}JNIEXPORT jint JNICALL Java_research_exam_com_jni_1demo_Java_1Interface_Add(JNIEnv *env, jobject obj, jint n1, jint n2){ return n1 + n2;}
5、ndk-build产生so库。
第三步:编写简单UI,调用so库。
activity_main.xml 源码参考如下:(只是简单的一个UI界面,测试so库。)
<?xml version="1.0" encoding="utf-8"?>
MainAcitvity.java 文件源码如下:
package research.exam.com.jni_demo;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private Java_Interface mm_ji = null; private TextView tv_show; private Button btn_add; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_show = (TextView)findViewById(R.id.tv_show); btn_add = (Button)findViewById(R.id.btn_add); btn_add.setOnClickListener(this); mm_ji = new Java_Interface(); //load so库 tv_show.setText(mm_ji.GetHellString()); } @Override public void onClick(View view) { if(btn_add == view) { On_btn_add(); } } private void On_btn_add() { int n1 = 3; int n2 = 8; tv_show.setText(mm_ji.Add(n1, n2) + ""); }}
配置一下app目录下的build.gradle, 在android{}中添加如下代码:
sourceSets { main { jni.srcDirs = [] jniLibs.srcDirs = ['src/main/libs'] //指定apk安装时候要加载so库的位置,默认情况下的加载位置为:src/main/jniLibs } }
最后使用模拟器来仿真。给出仿真结果如下图:
备注:javah和ndk-build方式生成so方式,注意事项,请参考这篇博客:https://blog.csdn.net/qq_41811438/article/details/102524296
---- The End.
更多相关文章
- Android情景分析之属性服务
- Android(安卓)音视频深入 十三 OpenSL ES 制作音乐播放器,能暂停
- android基础2——android工程目录结构
- Android(安卓)Q 带来哪些变化
- Android持久化技术之文件的读取与写入实例详解
- android MultiDex multidex原理下超出方法数的限制问题(三)
- 【Android】 Tablayout、XTablayout、SlidingTablayout的比较
- 第一次尝试翻译本书
- 在android中开发快速地搜索手机文件引擎实例