1. 程式人生 > >NDK探究之旅《十》——ndk專案實戰之Androidstudio開發經驗總結

NDK探究之旅《十》——ndk專案實戰之Androidstudio開發經驗總結

前幾次總結了一下關於C或C++的基礎知識及其開發流程。之前也大部分都是基於Elipse的。今天我們用AndroidStudio來開啟我們的第一個專案實戰。

但是基於AndroidStudio方面,以後趨勢都是AndroidStudio開發NDK的,我們也同樣的以後要用ES進行開發NDK.

先看效果圖:

Java程式碼中呼叫C程式碼

!Markdown

C程式碼呼叫Java程式碼中

Markdown

AndroidStudio環境配置:

  • 環境搭建

    • 在File–>Project Structure配置其路徑

    • 新增 ndk 後你會在 local.properties 這個檔案看到(路徑取決於你 ndk 的位置):

      Markdown

    • 在此處加上這句程式碼:android.useDeprecatedNdk=true好了,ndk 環境搭建完畢!

      Markdown

開發示例流程

1.編寫native方法

public class NdkJniUtils {
static {
    System.loadLibrary("myJniApp");
    System.loadLibrary("unstallApp");
}
public native String getCLanguageString();
public native void uninstallListener();

}

2.在src/main目錄下建立jni資料夾

3.生成.h標頭檔案

1.首先build或者是make project使專案生成.class檔案

2.在Androidstudio下的Terminal窗口裡生成.h標頭檔案

3.javah 包名.類名

如:

Javah jni.yyh.com.mycptojavanative.jni.cold.yyh.com.myndk01.NdkJniUtils

4.將生成的.h標頭檔案Copy到jni目錄下面

3.編寫C程式碼

在jni目錄裡右擊專案,新建.C檔案進行編寫C程式碼

現將生成的h檔案裡的內容Copy到.c檔案裡面去

去除不關聯的無用的內容

按照規範進行C程式碼程式碼的編寫

最後C程式碼示例:

#include <jni.h>

JNIEXPORT jstring JNICALL Java_cold_yyh_com_myndk01_NdkJniUtils_getCLanguageString (JNIEnv * env, jobject obj){
 return (*env)->NewStringUTF(env,"你好,ndk,我來了");
}

4.編寫Android.mk檔案

網上有很多博文來並沒有要求建立Android.mk檔案

但是為了正確的編譯C程式碼,防止編譯出錯,這裡我建議最好建立Android.mk

之前在Eclipse中建議將jni.h檔案copy到jni資料夾下面,這裡androids是之內的,無需做此操作

5.配置相關的gradle

宣告ndk標籤

如果不宣告ndk標籤,專案預設會建立一個libapp.so的檔案(存放目錄app\build\intermediates\ndk)

ndk {
            // 宣告建立so庫的檔名,會自動新增lib字首, 添加了字首,不會自動新增
            moduleName "serviceData"
            //宣告啟用Android日誌, 在c/c++的原始檔中使用的#include <android/log.h> 日誌將得到輸出
            ldLibs "log"//實現__android_log_print
            // 宣告建立指定cpu架構的so庫, 不宣告的話, 預設(gradle 1.5.0)會生成4中架構 多一種mips架構
            // 具體cpu架構的區別請參考:
            // for detailed abiFilter descriptions, refer to "Supported ABIs" @
            // https://developer.android.com/ndk/guides/abis.html#sa
            abiFilters "armeabi", "armeabi-v7a", "x86"
        }


//指定Android.mk檔案
    externalNativeBuild{
        ndkBuild{
            path "src/main/jni/Android.mk"
        }
    }

//指定so檔案路徑
sourceSets.main {
        // 1. 配置在根目錄libs下可以載入第三方so庫, (最好不要建立jniLibs, 在眾多的開源庫中可能會引起衝突,還沒發現)
        // 2. 執行時會自動將libs目錄下的so庫拷貝到指定目錄
        // 3. 如果自己建立的so不需要重新編譯,可以將(app/build/intermediates/transforms)生成的so拷貝到這個目錄
        jni.srcDirs = []
        // 如果是單個資料夾 可以直接這樣如下配置
       //jniLibs.srcDir 
       //設定目標的so存放路徑
        jniLibs.srcDir 'src/main/jniLibs'
    }

6.生成.so檔案

利用AndroidStudio進行生成.so檔案

build APK 、Make Project 、make Project Model 或者是 Rebuild Project 都能生成.so檔案

注意:之前有找不到.so檔案的情況,

這裡已經解決。

其實so檔案是存在 (app/build/intermediates/transforms)目錄下的

將生成的so檔案Copy到jniLibs資料夾下。

注意這裡要新建jnilibs。

這裡你也可以用命令指定生成ndk-build.cmd

7.在Java程式碼中呼叫動態連結庫(.so)

    在相應的地方進行載入so檔案 
    static {
        System.loadLibrary("myJniApp");
        System.loadLibrary("unstallApp");
    }

8.呼叫

示例程式碼:

private Button  btn_onclick,btn_onclick2;
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mTextView = (TextView) this.findViewById(R.id.test);
    btn_onclick = (Button) this.findViewById(R.id.btn_onclick);
    final NdkJniUtils jni = new NdkJniUtils();
    btn_onclick.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
        mTextView.setText(jni.getCLanguageString());

        }
    });
   findViewById(R.id.btn_onclick2).setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View view) {
          jni.uninstallListener();
           mTextView.setText("監聽SD卡狀態,查log日誌");
       }
   });

專案下載地址:

github相關下載連線:

如果下載不了,也可以通過csdn下載

之前基於Eclise相關所寫的介個專案

NDK探究之旅:

### 相信自己,沒有做不到的,只有想不到的
如果你覺得此文對您有所幫助,歡迎入群 QQ交流群 :232203809
微信公眾號:終端研發部

Markdown

(歡迎關注學習和交流)