android studio NDK開(kāi)發(fā),簡(jiǎn)單調(diào)用C、C++

前言

之前一直都是使用別人寫(xiě)好的so文件,沒(méi)有親自去寫(xiě)過(guò),于是決定研究一番。先說(shuō)說(shuō)NDK是什么呢?NDK其實(shí)就是一系列工具的集合。NDK有什么用呢?(1) NDK的發(fā)布,使“Java+C”的開(kāi)發(fā)方式終于轉(zhuǎn)正,成為官方支持的開(kāi)發(fā)方式。(2)NDK將是Android平臺(tái)支持C開(kāi)發(fā)的開(kāi)端。

環(huán)境配置

1. 在android studio中的setting-->Android SDK-->SDK Tools選項(xiàng)卡,下載NDK,CMake,LLDB三個(gè)工具

QQ截圖20170402094234.png

2. 新建一個(gè)項(xiàng)目,并勾選Include C++ support,一路next下去。

QQ截圖20170401171350.png

3. 配置android studio中ndk路徑。如果ndk路徑?jīng)]有自動(dòng)添加,則點(diǎn)擊select即可。并在local.properties配置文件中檢查是否正確配置路徑。

QQ截圖20170402095009.png
QQ截圖20170402095059.png

4. 配置ndk系統(tǒng)環(huán)境變量,并在配置完成后檢查配置是否成功

QQ截圖20170402095327.png

QQ截圖20170402095432.png

dos下命令:ndk-build;出現(xiàn)以下信息說(shuō)明配置成功

QQ截圖20170402095704.png

5. 設(shè)置as。將ndk版本差異檢測(cè)過(guò)濾掉,要不然項(xiàng)目無(wú)法編譯。添加:android.useDeprecatedNdk=true

QQ截圖20170402095914.png

6. 編寫(xiě)調(diào)用c的java代碼。注意:這里如果方法名報(bào)錯(cuò),不用管他。同時(shí)把MainActivity里的 static {System.loadLibrary("native-lib"); }剪切復(fù)制到新建的MathKit類中

public class MathKit {
public static native int square(int num);

// Used to load the 'native-lib' library on application startup.
static {
    System.loadLibrary("native-lib");
    }
}

7. 生成調(diào)用本地方法的.h頭文件。用as自帶的Terminal工具來(lái)生成。
命令:
進(jìn)入你項(xiàng)目的java文件夾下
cd app/src/main/java
com.axaet.ndk是你的完整包名,后面跟具體寫(xiě)有調(diào)用c代碼的java類
javah -jni com.axaet.ndk.MathKit

QQ截圖20170402101250.png
QQ截圖20170402101337.png

8. 生成jni文件夾。用于存放.h和.c文件,把步驟7生成的.h頭文件剪切到j(luò)ni文件夾里,并創(chuàng)建對(duì)應(yīng)的.c文件

QQ截圖20170402101858.png
QQ截圖20170402101747.png

9. 寫(xiě)c的測(cè)試代碼。include中指向你創(chuàng)建的.h頭文件 Java_com_axaet_ndk_MathKit_square;Java_包名類名方法名(參數(shù))**

#include "com_axaet_ndk_MathKit.h"
//注意方法名要和.h文件里的一樣
JNIEXPORT jint JNICALL Java_com_axaet_ndk_MathKit_square(JNIEnv *env, jclass cls, jint num) {
return num * num;
}

10.在build.gradle中配置生成so文件的信息,主要配置abiFilters

android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
    applicationId "com.axaet.ndk"
    minSdkVersion 15
    targetSdkVersion 25
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    externalNativeBuild {
        cmake {
            cppFlags ""
            abiFilters "armeabi-v7a", "armeabi", "x86"
        }
    }
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
externalNativeBuild {
    cmake {
        path "CMakeLists.txt"
    }
}
}

由于android studio 2.2以上使用CMake,所以需要配置CMakeLists.txt文件,修改生成后so文件名稱、添加.c文件的路徑

QQ截圖20170402102921.png

11. 用Make Project 生成so文件,然后運(yùn)行項(xiàng)目。然后就可以拿到so文件

QQ截圖20170402103505.png

12. 測(cè)試本地c代碼的調(diào)用。

public class MainActivity extends AppCompatActivity {

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

    // Example of a call to a native method
    TextView tv = (TextView) findViewById(R.id.sample_text);
    //必須先加載so文件,加載so文件在MathKit類中
    tv.setText(String.valueOf(MathKit.square(12)).concat("   ").concat(stringFromJNI()));
}
/**
 * A native method that is implemented by the 'native-lib' native library,
 * which is packaged with this application.
 */
public native String stringFromJNI();
}
下面是打包jar

13. 刪除一些無(wú)用的資源,如MainActivity,layout等,只留下和JNI有關(guān)的java類

QQ截圖20170405154544.png

14. 修改module的build.gradle文件

有如下幾個(gè)地方需要修改:
將最前面的apply plugin: 'com.android.application'修改為apply plugin: 'com.android.library'
將defaultConfig修改為:

defaultConfig {
minSdkVersion 14
targetSdkVersion 23
}

SDK的版本可以根據(jù)自己的版本來(lái)改

  1. 在最后加上
task deleteOldJar(type: Delete) {
delete 'build/outputs/test.jar'
}

task exportJar(type: Copy) {
from('build/intermediates/bundles/release/')
into('build/libs/')
include('classes.jar')
rename ('classes.jar', 'test.jar')
}

exportJar.dependsOn(deleteOldJar, build)

15.導(dǎo)出jar包
首先打開(kāi)Gradle

打開(kāi)app->Tasks->other->exportJar


然后雙擊exportJar就可以了,然后再'build/intermediates/bundles/release/'路徑就可以找到classes.jar
當(dāng)然混淆可以自己視情況添加。
項(xiàng)目源碼

參考文檔[http://www.2cto.com/kf/201610/555224_2.html]
[http://www.open-open.com/lib/view/open1434523603692.html]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容