《关于ndk jni开发和so文件的生成》
一、功能需求
使用java调用c语言的方法,返回一个字符串,同时生成so文件;ndk环境配置http://blog.csdn.net/true_maitian/article/details/78250848
二、先看下结构图
(0)MainActivity.java
这里可以理解为我们需要用到.c文件里面的方法,我们需要先加载他,同时实例化native对应的方法。
public class MainActivity extends AppCompatActivity { // 加载jni文件 static { System.loadLibrary("MyJni"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Example of a call to a native method TextView tv = (TextView) findViewById(R.id.sample_text); tv.setText(stringFromJNI()); Button button = (Button) findViewById(R.id.buttion); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String str = stringFromJNI(); Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show(); } }); } /** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. * 定义一个jni方法 */ public native String stringFromJNI(); }
(1)先在main目录先建一个jni的目录,然后编写.c文件
// // Created by Laizhen on 2017/10/16. // #include <jni.h> jstring Java_com_bql_ndks_MainActivity_stringFromJNI(JNIEnv *env,jobject thiz) { return (*env)->NewStringUTF(env, "I`m Str from jni libs!"); }很简单的返回一个字符串"I'm Str from jni libs!"
(2)根据这个sssss.c文件(名字可以随意取)生成.h文件
External Tools 添加一个生成.h文件的cmd工具。
$JDKPath$\bin\javah.exe
-classpath . -jni -o $ModuleFileDir$\src\main\jni\$Prompt$ $FileClass$
$ModuleFileDir$\src\main\Java
写完之后,点击ok即可。
(3)ndk-build tools。
F:\Android\SDK\ndk-bundle\ndk-build.cmd
第二行不填
$ProjectFileDir$\app\src\main
ok
这样两个工具快捷就生成了。
(4).h文件就生成了。结构图中,zzz.h就是了。此处还有一个kong.c文件,是空文件。
(5)Android.mk文件编写
APP_PLATFORM := android-8 LOCAL_PATH := ${call my-dir} include $(CLEAR_VARS) LOCAL_MODULE := MyJni LOCAL_SRC_FILES := sssss.c include $(BUILD_SHARED_LIBRARY)第二行是定位源文件,指向Android系统提供的my-dir的宏功能;
第三行是编译模块的开始;
第四行是编译内容,也就是你编写模块名称,后面生成so文件也会用到这个名字;
第五行是建立和组装这个模块的原文件列表,其实就是也就是编译里面的方法;
第六行是编译模块结束,同时类型设定为共享库。
(6)Application.mk
APP_STL := gnustl_static APP_CPPFLAGS := -frtti -fexceptions APP_ABI := armeabi-v7a #这句是设置生成的cpu指令类型,提示,目前绝大部分安卓手机支持armeabi,libs下太多类型,编译进去 apk 包会过大 APP_PLATFORM := android-8 #这句是设置最低安卓平台,可以不弄该文件的主要擢用
该文件的主要作用是:描述应用程序需要那些模块。
(7)最后.so文件生成:使用external tools (跟上面javah工具一样)
这个搞定之后就会跟我的结构图一样了。main文件下面会新增libs,obj两个文件夹。
三、如果只是按上面的走,应该是会报错的,我们需要配置一下内容
(1)build.gradle
abiFilters这里面对应的ABI类型跟android.mk里面的需要对应,你选择的类型越多,他就会也相应的生成对应文件同时也有相应的so文件生成。
android { compileSdkVersion 26 buildToolsVersion "26.0.1" defaultConfig { applicationId "com.bql.ndks" minSdkVersion 14 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" ndk{ moduleName "MyJni" ldLibs "log" abiFilters "armeabi-v7a" } } sourceSets { main{ jniLibs.srcDirs = ['src/main/libs'] jni.srcDirs = [] } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }(2)local.properties文件
## This file is automatically generated by Android Studio. # Do not modify this file -- YOUR CHANGES WILL BE ERASED! # # This file must *NOT* be checked into Version Control Systems, # as it contains information specific to your local configuration. # # Location of the SDK. This is only used by Gradle. # For customization when using a Version Control System, please read the # header note. #Mon Oct 16 13:52:06 CST 2017 ndk.dir=F\:\\Android\\sdk\\ndk-bundle sdk.dir=F\:\\Android\\sdk打完收工