Android Studio 基于mk 开发ndk 使用c

1. 创建一个普通android工程
2. gradle配置

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "mk.denganzhi.com.myapplication"
        minSdkVersion 15
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
//        externalNativeBuild {
//            cmake {
//                cppFlags ""
//                abiFilters "armeabi-v7a"
//            }
//        }
        externalNativeBuild {
            //1. 配置编译需要生成的库
            ndkBuild {
                cppFlags ""
                abiFilters "armeabi-v7a","x86"
            }
        }
    // 2. 配置打包需要打入的库,只打入armeabi-v7a
        ndk{
            moduleName "moduleName"
        //    ldLibs "log"//实现__android_log_print
            abiFilters "armeabi-v7a"
        }

    }


    //3. defaultConfig 外externalNativeBuild 指定  mk 路径
    externalNativeBuild {
        ndkBuild {
            path "src/main/cpp/Android.mk"
        }
    }



    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            // 4. 指定程序打包的库,如果有arm库,x86库,那么程序打开的时候只打开arm库
            // .c 中 log 不能输出问题,按照做了,无法解决
            // https://www.cnblogs.com/taoweiji/p/4564572.html  log库解决方案
        }

    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}


3. 创建native-lib.c, 在main/cpp目录下

#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include <android/log.h>

//#define  LOG_TAG    "native-dev"
//#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
//#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
//#define LOGP(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)


JNIEXPORT jstring JNICALL Java_com_example_hava_MainActivity_Hello  // 返回值+ 全类名
        (JNIEnv * env, jobject obj){
    char* cstr = "hello from a";
    // env 是二级指针,NewStringUTF 到  jni.h中去找  对应函数
    jstring jstr = (*env)->NewStringUTF(env, cstr);

    //LOGE("Java_com_example_hava_MainActivity_Hello");

    return jstr;
}

4. 创建Android.mk, 在 main/cpp目录下,和.c文件同级目录,避免找不到

 LOCAL_PATH := $(call my-dir)
# call 调用  my-dir 函数 返回 当前 mk路径 赋值给 LOCAL_PATH

# 清理临时动态库文件
    include $(CLEAR_VARS)
#编译生成的文件的类库叫什么名字
    LOCAL_MODULE    := hello
    #要编译的c++文件
    LOCAL_SRC_FILES := native-lib.c
# 生成动态库
    include $(BUILD_SHARED_LIBRARY)

5. 运行

public class MainActivity extends AppCompatActivity {

    static {
        System.loadLibrary("hello");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void  showMsg(View view){
        String str= stringFromJNI();
        Toast.makeText(MainActivity.this,str,Toast.LENGTH_SHORT).show();
    }

    public native String stringFromJNI();
}

    建议: ndk对mk的支持google已经接近放弃,推荐使用cmake 

发布了65 篇原创文章 · 获赞 61 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/dreams_deng/article/details/104543239