android studio jni環境搭建

今天說一下 studio ndk開發的環境搭建。相比之下比eclipse的簡化了許多,不需要麻煩的步驟。
先簡單說下環境搭建:
環境只需要安裝ndk就好。
如果沒有ndk,按照下面步驟。
安裝ndk
這裏寫圖片描述
這裏寫圖片描述
其中ndk目錄是在sdk目錄下的 ndk-bundle下。一路next finish行了。
如果已經有ndk,配置上就可以了。

《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《《

配置完畢ndk正式開始例程。
總共分三個步驟

  1. 創建工程,修改工程配置
  2. 寫本地方法名,生產頭文件(如果需要)
  3. 編寫c/c++代碼

    其中生產頭文件 不是必須。但推薦還是生產。頭文件包含方法的前面,自己寫很容易搞錯,非常容易寫錯。。。

正式開始
第一部創建配置工程
1.先創建一個model。檢查下local.properties文件是有了ndk目錄
ndk.dir=D:\Programming\Sdkstudiedo\ndk-bundle
sdk.dir=D:\Programming\Sdkstudiedo
沒有檢查ndk目錄。
2修改build.gradle。需要修改三處。
1)project的build.gradle
2)model的build.gradle
3)project的 gradle\wrapper\gradle-wrapper.properties
如圖
這裏寫圖片描述

首先說project的build.gradle。
修改 classpath
classpath 'com.android.tools.build:gradle-experimental:0.2.0'。
如圖。
這裏寫圖片描述
其次修改 project的gradle-wrapper.properties。修改distributionUrl=https://services.gradle.org/distributions/gradle-2.5-all.zip
如圖。
這裏寫圖片描述

最後需要修改model的build.gradle。 挺多的

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion = 23
        buildToolsVersion = "23.0.2"

        tasks.withType(JavaCompile) {
            //指定編譯JDK版本
            sourceCompatibility = JavaVersion.VERSION_1_7
            targetCompatibility = JavaVersion.VERSION_1_7
        }

        defaultConfig.with {
            applicationId = "cn.jni.com.jnidemo"
            minSdkVersion.apiLevel = 19
            // Unable to load class com.android.build.gradle.managed.ProductFlavor_Impl
            targetSdkVersion.apiLevel = 23
            versionCode = 1
            versionName = "1.0"
        }

    }
    android.buildTypes {
        release {
            minifyEnabled = false
            proguardFiles += file('proguard-rules.pro')
        }
    }


    android.ndk {
        moduleName = "test"
        ldLibs +="log"
        abiFilters +="armeabi"
        abiFilters +="armeabi-v7a"
        abiFilters +="x86"
        cppFlags += "-std=c++11"
        cppFlags += "-fexceptions"
        cppFlags += "-I${file("src/main/jni//include")}".toString()
        ldLibs += ["android", "log"]
        stl = "gnustl_shared"
    }

    android.productFlavors {
        create("arm7") {
            ndk.abiFilters.add("armeabi-v7a")
        }
        create("arm8") {
            ndk.abiFilters.add("arm64-v8a")
        }

    }
}


dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.1.0'
}

注意區別
1apply plugin: ‘com.android.application’改爲
apply plugin: ‘com.android.model.application’;
2.原來的 xxx : xx改爲xxx = ;
3.android目錄外層多了一層model
4.有些從android提出來了。結構改變
建議直接複製上面的,修改一下工程名字和庫名字直接用就行。
applicationId 和moduleName 修改。

修改完文件,進行第二步驟
第二步,創建本地方法,生產頭文件

1.首先新建一個java類,名字叫做。JniUtils

public class JniUtils {

    static {
        System.loadLibrary("test");//之前在build.gradle裏面設置的so名字,必須一致
    }

    public static native String getStringFormC();

}

其中靜態代碼塊裏面的是加載so庫,名字與model的build.gradle配置的 android.ndk 下面的 moduleName = “test”必須一樣。
然後聲明方法,方法比普通java方法多了native。

2.生產頭文件。由於方法名非常長非常噁心,容易寫錯,建議生產頭文件來copy方法簽名就行。
首先創建jni目錄,
這裏寫圖片描述
然後使用javah 命令來生產頭文件。
javah -d 生產頭文件存放目錄 java類包名

比如我現在在main下面的java文件夾裏面,那我運行

javah -d ../jni  cn.jni.com.jnidemo.JniUtils

就會在jni下生成。h了。studio裏面有控制檯,和cmd一樣。
這裏寫圖片描述

最後一步編寫本地方法就行了
在jni目錄下新建一個c文件,名字隨意,打開剛纔生產的.h,然後複製剛纔的函數聲明。
JNIEXPORT jstring JNICALL Java_cn_jni_com_jnidemo_JniUtils_getStringFormC
(JNIEnv *, jclass);
方法名字就是很長。所以還是生成頭文件安全一點。
然後再。c文件裏面包含這個頭文件和jni.h,定義這個函數就可。代碼如下:

#include<jni.h>
#include"cn_jni_com_jnidemo_JniUtils.h"
JNIEXPORT jstring JNICALL Java_cn_jni_com_jnidemo_JniUtils_getStringFormC (JNIEnv *env, jobject obj){
      return (*env)->NewStringUTF(env,"String from c");
      }

這樣步驟都寫完了。只要在java層調用就行了
在activity裏面掉用和本地方法一樣

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView  textView = (TextView) findViewById(R.id.tv);
        textView.setText(JniUtils.getStringFormC());
    }
}

經過以上三個步驟就完成了java調用c方法。運行結果
這裏寫圖片描述

demo地址:http://download.csdn.net/detail/spinchao/9523830

下面發現了一種簡便的方法。
直接見一個常規項目,然後,寫本地方法,生產頭文件,比如在main的 java文件夾下執行
javah -d ../jni com.jniexample.spc.helloworld.MainActivity。
就會在main下面創建一個jni目錄,裏面有生產好的h頭文件, 然後再項目的build.gradle裏面配置一下so庫,在 defaultConfig 裏面配置
ndk{
moduleName “MyJni” //設置庫(so)文件名稱
}
然後ok,直接在文件裏面加載so 運行。
這樣還支持instant run。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章