一、功能需求

        使用java调用c语言的方法,返回一个字符串,同时生成so文件;ndk环境配置

二、先看下结构图

Android 的so文件解析_android ndk

(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文件

Android 的so文件解析_jni开发_02

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。

Android 的so文件解析_ndk开发_03

F:\Android\SDK\ndk-bundle\ndk-build.cmd

第二行不填

$ProjectFileDir$\app\src\main

ok

这样两个工具快捷就生成了。

(4).h文件就生成了。结构图中,zzz.h就是了。此处还有一个kong.c文件,是空文件。

Android 的so文件解析_android ndk_04

(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

打完收工