Android Studio 1.2 开发JNI工程

  • 添加native接口

注意写好native接口和System.loadLibrary()即可了,并无特别之处。

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

20141215184150750
这一步骤执行一下,验证工程中并无其它错误,并对工程进行了编译,生成了.class文件.
.class文件的生成路径是在 app_path/build/intermediates/classes/debug下的.如下图:20141215184245654

  • javah生成c头文件

点击"View->Tool Windows->Terminal",即在Studio中进行终端命令行工具.执行如下命令生成c语言头文件。
这里需要注意的是要进入 \app\src\main的目录下执行javah命令,为的是生成的 .h 文件同样是在\app\src\main路径下,可以在Studio的工程结构中直接看到。

$ cd app/src/main

$ javah -d jni -classpath %Android_SDK_Home%\platforms
\android-21\android.jar;..\..\build\intermediates\classes\debug lab.sodino.jnitest.MainActivity

最后的生成结果:20141215184427109

  • 编辑c文件

在main.c文件中实现头文件中的方法,具体功能为直接return回一个String,并且使用android_log打印出相关日志。
代码如下:

/* 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

20141215184556957

  • Jni目录下手工创建Application.mk

里面内容如下:

APP_PLATFORM := android-21
  • Jni目录下手工创建Android.mk

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文件了.

如果

Android_studio_jni

跟我的代码布局类似,增加了一个include目录,里面包含引用的第三方头文件,那么就比较折腾,因为编译的时候会报告找不到头文件,而通过设置

LOCAL_C_INCLUDES += $(LOCAL_PATH)/include/

是可以通过命令行编译通过的,但是却不能在Gradle中编译通过。

这种情况下,需要放弃Android Studio 自带的配置,修改app目录下的“build.gradle”

原始内容如下:

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'])
}

修改后的内容如下:

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

发布者

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注