-
添加native接口
注意写好native接口和System.loadLibrary()即可了,并无特别之处。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class MainActivity extends Activity{ static { System.loadLibrary("JniTest"); } public native String getStringFromNative(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView txtView = (TextView) findViewById(R.id.txt); txtView.setText(getStringFromNative()); } } |
-
执行Build->Make Project
这一步骤执行一下,验证工程中并无其它错误,并对工程进行了编译,生成了.class文件.
.class文件的生成路径是在 app_path/build/intermediates/classes/debug下的.如下图:
-
javah生成c头文件
点击"View->Tool Windows->Terminal",即在Studio中进行终端命令行工具.执行如下命令生成c语言头文件。
这里需要注意的是要进入 \app\src\main的目录下执行javah命令,为的是生成的 .h 文件同样是在\app\src\main路径下,可以在Studio的工程结构中直接看到。
1 2 3 4 |
$ cd app/src/main $ javah -d jni -classpath %Android_SDK_Home%\platforms \android-21\android.jar;..\..\build\intermediates\classes\debug lab.sodino.jnitest.MainActivity |
-
编辑c文件
在main.c文件中实现头文件中的方法,具体功能为直接return回一个String,并且使用android_log打印出相关日志。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> #include <android/log.h> #ifndef LOG_TAG #define LOG_TAG "ANDROID_LAB" #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) #endif /* Header for class lab_sodino_jnitest_MainActivity */ #ifndef _Included_lab_sodino_jnitest_MainActivity #define _Included_lab_sodino_jnitest_MainActivity #ifdef __cplusplus extern "C" { #endif /* * Class: lab_sodino_jnitest_MainActivity * Method: getStringFromNative * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_lab_sodino_jnitest_MainActivity_getStringFromNative (JNIEnv * env, jobject jObj){ LOGE("log string from ndk."); return (*env)->NewStringUTF(env,"Hello From JNI!"); } #ifdef __cplusplus } #endif #endif |
-
配置NDK
-
Jni目录下手工创建Application.mk
里面内容如下:
1 |
APP_PLATFORM := android-21 |
-
Jni目录下手工创建Android.mk
1 2 3 4 5 6 7 8 9 10 |
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:= JniTest LOCAL_LDLIBS+= -L$(SYSROOT)/usr/lib -llog LOCAL_SRC_FILES := main.c include $(BUILD_SHARED_LIBRARY) |
再执行"Build->Rebuild Project",就可以编译出so文件了.
如果
跟我的代码布局类似,增加了一个include目录,里面包含引用的第三方头文件,那么就比较折腾,因为编译的时候会报告找不到头文件,而通过设置
1 |
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include/ |
是可以通过命令行编译通过的,但是却不能在Gradle中编译通过。
这种情况下,需要放弃Android Studio 自带的配置,修改app目录下的“build.gradle”
原始内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
apply plugin: 'com.android.application' android { compileSdkVersion 22 buildToolsVersion "22.0.1" defaultConfig { applicationId "mobibrw.longsky.com.sctpclient" minSdkVersion 21 targetSdkVersion 22 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) } |
修改后的内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import org.apache.tools.ant.taskdefs.condition.Os apply plugin: 'com.android.application' android { compileSdkVersion 22 buildToolsVersion "22.0.1" defaultConfig { applicationId "mobibrw.longsky.com.sctpclient" minSdkVersion 21 targetSdkVersion 22 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets.main { jni.srcDirs = [] jniLibs.srcDir './src/main/libs' } task ndkBuild(type:Exec) { def Properties localProps = new Properties() localProps.load(new FileInputStream("local.properties")) def ndk_dir = localProps['ndk.dir'] def ndk_build_cmd = "$ndk_dir/ndk-build" if (Os.isFamily(Os.FAMILY_WINDOWS)) { ndk_build_cmd = "$ndk_dir/ndk-build.cmd" } commandLine ndk_build_cmd, '-j', Runtime.runtime.availableProcessors(),"NDK_OUT=$buildDir/native/obj","NDK_PROJECT_PATH=./src/main" } tasks.withType(JavaCompile) { compileTask->compileTask.dependsOn ndkBuild } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) } |
参考 http://blog.csdn.net/sodino/article/details/41946607