按照步驟執行:java
local.properties文件(sdk和ndk配置路徑):android
## This file is automatically generated by Android Studio. # Do not modify this file -- YOUR CHANGES WILL BE ERASED! # # This file should *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. sdk.dir=E\:\\AndroidSDK ndk.dir=E\:\\AndroidNDK\\android-ndk-r14b
CMakeLists.txt文件 :app
cmake_minimum_required(VERSION 3.4.1) include_directories( ${CMAKE_SOURCE_DIR}/head) add_library(jni_more SHARED ${CMAKE_SOURCE_DIR}/cpp/More.cpp) find_library(lib-log log) target_link_libraries(jni_more ${lib-log})
app : build.gradle文件:ide
apply plugin: 'com.android.application' android { compileSdkVersion 28 defaultConfig { applicationId "com.zzm.more" minSdkVersion 19 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" externalNativeBuild{ cmake{ abiFilters "arm64-v8a" , "armeabi-v7a" } } } externalNativeBuild { cmake{ path "src/main/jni/CMakeLists.txt" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' 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' }
MainActivity.java文件:gradle
package com.zzm.more; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; public class MainActivity extends AppCompatActivity { static { System.loadLibrary("jni_more"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i("22m",test("zengzeming")); } public static native String test(String name); }
xxx.cpp文件:ui
#include "jni.h" #include "android/log.h" //#include "../head/more.h" #include <stdio.h> jstring test(JNIEnv* env,jclass ,jstring name){ const char* name_char=env->GetStringUTFChars(name,false); __android_log_print(ANDROID_LOG_INFO,"22m","name : %s",name_char); return env->NewStringUTF("zengzeming"); } const char* classPathName="com/zzm/more/MainActivity"; const JNINativeMethod methods[]={ { "test","(Ljava/lang/String;)Ljava/lang/String;",(void*)test } }; int registerNativeMethods(JNIEnv* env, const char* className, const JNINativeMethod* gMethods,int numMethods){ jclass clazz; clazz=env->FindClass(className); if(clazz==NULL){ __android_log_print(ANDROID_LOG_INFO,"22m","native registration unable to find class '%s'",className); return JNI_FALSE; } if(env->RegisterNatives(clazz,gMethods,numMethods)<0){ __android_log_print(ANDROID_LOG_INFO,"22m","RegisterNatives failed for '%s'",className); return JNI_FALSE; } return JNI_TRUE; } int registerNatives(JNIEnv* env){ if(!registerNativeMethods(env,classPathName,methods, sizeof(methods)/ sizeof(methods[0]))){ return JNI_FALSE; } return JNI_TRUE; } typedef union { JNIEnv* env; void* venv; }UnionJNIEnvToVoid; jint JNI_OnLoad(JavaVM* vm, void* ){ UnionJNIEnvToVoid uenv; uenv.venv=NULL; jint result =-1; JNIEnv* env=NULL; __android_log_print(ANDROID_LOG_INFO,"22m","JNI_OnLoad"); if(vm->GetEnv(&uenv.venv,JNI_VERSION_1_6)!=JNI_OK){ __android_log_print(ANDROID_LOG_INFO,"22m","ERROR: GetEnv failed"); goto fail; } env=uenv.env; if(registerNatives(env)!=JNI_TRUE){ __android_log_print(ANDROID_LOG_INFO,"22m","ERROR: registerNatives failed"); goto fail; } result=JNI_VERSION_1_6; fail: return result; }
run起來的log信息:this
2019-01-05 07:20:12.808 30571-30571/com.zzm.more I/22m: JNI_OnLoad
2019-01-05 07:20:13.100 30571-30571/com.zzm.more I/22m: name : zengzeming
2019-01-05 07:20:13.100 30571-30571/com.zzm.more I/22m: zengzemingspa