Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android Studio NDK基礎使用

Android Studio NDK基礎使用

編輯:關於android開發

Android Studio NDK基礎使用


NDK是什麼?

Android平台是基於java實現,運行於虛擬機Dalvik;故而使用Android SDK創建應用程序需要使用java語言來編寫實現。不過並不僅限於使用java,google在發布android之初就宣稱支持持JNI編程方式,也就是第三方應用完全可以通過JNI調用自己的C動態庫,即在Android平台上,“Java+C”的編程方式是一直都可以實現的。NDK即為了方便你創建應用時調用本地C/C++的一系列工具集合。
The NDK is a toolset that allows you to implement parts of your app using native-code languages such as C and C++. For certain types of apps, this can be helpful so you can reuse existing code libraries written in these languages, but most apps do not need the Android NDK.

官方NDK文檔:http://wear.techbrood.com/tools/sdk/ndk/

什麼時候使用NDK?

Before downloading the NDK, you should understand that the NDK will not benefit most apps. As a developer, you need to balance its benefits against its drawbacks. Notably, using native code on Android generally does not result in a noticable performance improvement, but it always increases your app complexity. In general, you should only use the NDK if it is essential to your app—never because you simply prefer to program in C/C++.
官方清楚的描述了大部分應用並不會因為使用NDK而獲得明顯的性能收益,反而有可能導致應用的復雜度增加,兼容性變差等。Google建議在需要在處理需要大量計算/高CPU消耗的工作時使用NDK來提高運算處理效率,例如:游戲引擎、信號處理、圖像處理等。

而實際使用NDK時往往還會考慮到:
1. 代碼的保護,由於apk的java層代碼很容易被反編譯,而C/C++庫反匯難度較大。
2. 為了方便地使用現存的開源庫,大部分現存的開源庫都是用C/C++代碼編寫的。
3. 跨平台考慮,用C/C++寫得庫可以方便在其他的嵌入式平台上再次使用。

AS 上使用NDK 示例

使用NDK,當然要先下載最新NDK工具:http://developer.android.com/ndk/downloads/index.html

配置項目的NDK路徑:
這裡寫圖片描述

查看local.properties是否定義好NDK路徑:
這裡寫圖片描述

Project Gradle NDK配置
更改project的gradle.properties文件,加入android.useDeprecatedNdk=true,使得項目支持NDK:

這裡寫圖片描述

修改app下build.gradle的defaultConfig,配置native c/c++編譯本地so庫:
這裡寫圖片描述

申明JNI函數,在java代碼內編寫需要實現JNI的native函數:

package com.example.jokerlee.myapplication;

/**
 * Created by jokerlee on 16-3-31.
 */
public class JniTest {

    //使用jni需要加載本地編譯出來的so庫,名稱即為上一步配置的ndk moduleName
    static {
        System.loadLibrary("jniTest");
    }

    public static  native String getStringFromJni();
}

Rebuild Project之後NDK工具會在app的build/intermediates目錄下產生一個classses文件夾:
這裡寫圖片描述

打開AS的terminal執行使用javah命令將java class聲明的JNI方法轉化成C\C++頭文件
關於javah命令詳解可參考:http://blog.csdn.net/zzhays/article/details/10514767
這裡寫圖片描述

在當前debug目錄生成com_example_jokerlee_myapplication_JniTest.h:<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;"> /* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class com_example_jokerlee_myapplication_JniTest */ #ifndef _Included_com_example_jokerlee_myapplication_JniTest #define _Included_com_example_jokerlee_myapplication_JniTest #ifdef __cplusplus extern "C" { #endif /* * Class: com_example_jokerlee_myapplication_JniTest * Method: getStringFromJni * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_example_jokerlee_myapplication_JniTest_getStringFromJni (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif

然後就是根據該頭文件創建c/cpp文件TestJni.cpp實現頭文件中的函數聲明,並將這些頭文件和c/cpp文件移動到main/src目錄下:

//
// Created by jokerlee on 16-3-31.
//
#include "com_example_jokerlee_myapplication_JniTest.h"

JNIEXPORT jstring JNICALL Java_com_example_jokerlee_myapplication_JniTest_getStringFromJni
  (JNIEnv * env, jclass ){
    return env->NewStringUTF("這裡是來自c的string");
  }

這裡寫圖片描述

使用JNI函數

前面完成各種配置以及c/c++文件的編寫之後,在應用內若需要實現JNI調用native函數,則需要先加載native code編譯出來的so庫:

//jniTest為庫的名稱,即為配置在app build.gradle defaultConfig的moduleName
System.loadLibrary("jniTest");
package com.example.jokerlee.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

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

        Log.d("test", JniTest.getStringFromJni() );
    }
}

這裡寫圖片描述

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved