1)samples目錄。這個目錄包含了Google為NDK開發(fā)撰寫的一些小例子,包括本地JNI開發(fā),圖片處理,多個庫文件開發(fā)等等,這些例子雖小但面面俱到,能看懂samples目錄下的小例子程序,那么對于NDK開發(fā)來說,就很好應(yīng)付了。
站在用戶的角度思考問題,與客戶深入溝通,找到豐滿網(wǎng)站設(shè)計與豐滿網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗(yàn)好的作品,建站類型包括:成都做網(wǎng)站、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、主機(jī)域名、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋豐滿地區(qū)。2)docs目錄。這個目錄下存放的都是Google給開發(fā)者提供的文檔,指導(dǎo)開發(fā)者怎樣在Android環(huán)境下進(jìn)行NDK開發(fā),這個非常重要。
3)sources目錄。由于Android是開源操作系統(tǒng),作為Android的一部分的NDK,同樣也是開源的,這個目錄下存放的是NDK源碼。
4)platforms目錄。里面存放的是當(dāng)前ndk版本所支持的所有android平臺的版本,做NDK開發(fā)的C代碼也是可以指定由某個特定版本平臺下編譯,該platforms目錄下存放的是不同版本所包含的C的庫文件和頭文件,不同版本有些微小的變化。
5)prebuilt目錄。這是提供給在Windows下開發(fā)ndk程序的一些工具集。
6)build目錄。里面存放大量的Linux編程腳本和Windows下的批處理文件,用來完成ndk開發(fā)中的交叉編譯。
首先,我先列出NDK開發(fā)的簡單步驟,然后再以此為大綱,用一個Hello World的實(shí)例講述一下NDK開發(fā):
(1)創(chuàng)建一個android工程
(2)JAVA代碼中寫聲明native 方法 public native String helloFromJNI();
(3)創(chuàng)建jni目錄,編寫c代碼,方法名字要對應(yīng)在c代碼中導(dǎo)入jni.h頭文件
(4)編寫Android.mk文件
(5)Ndk編譯生成動態(tài)庫
(6)Java代碼load 動態(tài)庫.調(diào)用native代碼
下面就按照上述的步驟建立一個HelloWorld小案例來一步一步實(shí)現(xiàn)NDK開發(fā)
package com.example.ndkdemo01;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity {
static{
System.loadLibrary("Hello"); //System.loadLibrary(String 文件名);是用來加載動態(tài)庫的方法,其中參數(shù)類型是字符串,參數(shù)是Android.mk文件中LOCAL_MODULE定義的名稱。
}
private Button bt_click;
public native String javaFromJNI(); //聲明native方法
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_click= (Button) this.findViewById(R.id.bt_click);
bt_click.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub Toast.makeText(MainActivity.this, javaFromJNI(),
Toast.LENGTH_SHORT).show();
}
});
}
}
3)多出來的傳遞參數(shù),JNIEnv* env和jobject thiz是底層函數(shù),必須要帶的參數(shù)。env開發(fā)者利用此參數(shù)做查詢和傳化數(shù)據(jù)類型(比如將jintarray轉(zhuǎn)換成int數(shù)組,在以后的章節(jié)中會詳細(xì)說明)。thiz表示這個調(diào)用這個函數(shù)的類對象,本文中就是MainActivity的對象。
#include<stdio.h>
#include<jni.h>
jstring Java_com_example_ndkdemo01_MainActivity_javaFromJNI(JNIEnv* env, jobject obj) {
return (*(*env)).NewStringUTF(env, "hello jni!");
}
3.1 這個Android.mk文件怎么寫呢?這時候我們得打開NDK的文檔來看看了,位置E:/NDK/android-ndk-r10d/docs/Start_Here.html,找到
好,我們就先在jni目錄下創(chuàng)建一個Android.mk的文件,將上面的這段話復(fù)制粘貼進(jìn)去,將LOCAL_MODULE和LOCAL_SRC_FILES修改成我們自己寫成的C文件的名稱:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Hello
LOCAL_SRC_FILES := Hello.c
include $(BUILD_SHARED_LIBRARY)
3.2 Application.mk文件的目的是描述在你的應(yīng)用程序中所需要的模塊(即動態(tài)庫或靜態(tài)庫)。
Application.mk文件通常被放置在 $PROJECT/jni/Application.mk下,$PROJECT指的是您的項目。
要將CC++代碼編譯為SO文件,光有Android.mk文件還不行,還需要一個Application.mk文件。
3.3 NDK程序生成支持多種CPU架構(gòu)的SO包
在我們android NDK項目的根目錄下面有一個libs文件夾,如下圖所示,這個文件夾下面有下面七個文件夾:arm64-v8a,armeabi ,armeabi-v7a, mips, mips64,x86 ,x86_64。我們的c代碼編譯成SO庫就會放在這七個文件夾中的一個或多個中。那么這些文件夾中的SO文件有什么區(qū)別? arm64-v8a,armeabi ,armeabi-v7a, mips, mips64,x86 ,x86_64是表示七種不同的cpu的架構(gòu),我們知道一般的手機(jī)或平板都是用arm的cpu,不同的cpu的特性不一樣,armeabi就是針對普通的或舊的arm v5 cpu,armeabi-v7a是針對有浮點(diǎn)運(yùn)算或高級擴(kuò)展功能的arm v7 cpu。應(yīng)用程序二進(jìn)制接口(Application Binary Interface)定義了二進(jìn)制文件(尤其是.so文件)如何運(yùn)行在相應(yīng)的系統(tǒng)平臺上,從使用的指令集,內(nèi)存對齊到可用的系統(tǒng)函數(shù)庫。在Android系統(tǒng)上,每一個CPU架構(gòu)對應(yīng)一個ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。
NDK開發(fā)中,如何編譯生成arm64-v8a,armeabi ,armeabi-v7a, mips, mips64,x86 ,x86_64七個文件夾下面的.so文件,可以在Application.mk里可以配置以下宏指定ABI生成機(jī)器代碼:
TARGET_CPU_API := all
APP_ABI := all
或者是
TARGET_CPU_API := armeabi armeabi-v7a x86 x86_64 arm64-v8a mips mips64
APP_ABI := armeabi armeabi-v7a x86 x86_64 arm64-v8a mips mips64
默認(rèn)情況下,NDK的編譯系統(tǒng)根據(jù) "armeabi" ABI生成機(jī)器代碼??梢允褂肁PP_ABI 來選擇一個不同的ABI。
比如:為了在ARMv7的設(shè)備上支持硬件FPU指令??梢允褂?nbsp;APP_ABI := armeabi-v7a
或者為了支持IA-32指令集,可以使用 APP_ABI := x86
或者為了同時支持這三種,可以使用 APP_ABI := armeabi armeabi-v7a x86
或者有時候可能只需要兼容幾種cpu類型,則“TARGET_CPU_API :=” 和 “APP_ABI :=”隨便指定上面六種中任意一種。
程序中可能會出現(xiàn)下面類似的錯誤,主要是由于沒有生成對應(yīng)支持CPU類型的SO文件
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/cn.com.chinatelecom.account-1/base.apk"],nativeLibraryDirectories=[/data/app/cn.com.chinatelecom.account-1/lib/arm64, /vendor/lib64, /system/lib64]]] couldn't find "libFeedbackUtils.so"
4,ndk編譯生成動態(tài)庫
在eclipse中點(diǎn)擊項目,右擊->>Android Tools->>Add Native Support... 。隨后會有一個對話框彈出,在輸入框里輸入模塊名稱??梢钥吹骄幾g通過了,下面刷新一下工程,就可以看到工程libs目錄下多了個libHello.so的文件,這個就是Android認(rèn)識的動態(tài)庫了。
編譯出來這個libHello.so文件后,就需要在Java代碼中加載這個.so的庫文件了,代碼很簡單,然后Toast一下看看效果:
System.loadLibrary(String 文件名);是用來加載動態(tài)庫的方法,其中參數(shù)類型是字符串,參數(shù)是Android.mk文件中LOCAL_MODULE定義的名稱。
參考博客 http://blog.csdn.net/allen315410/article/details/41805719 和http://www.cnblogs.com/yaozhongxiao/archive/2012/03/06/2381586.html和http://www.jianshu.com/p/cb05698a1968?from=timeline&isappinstalled=0
本文標(biāo)題:二、AndroidNDK開發(fā)---從HelloWord學(xué)起-創(chuàng)新互聯(lián)
文章路徑:http://jinyejixie.com/article46/gpjhg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、Google、網(wǎng)站策劃、網(wǎng)站導(dǎo)航、靜態(tài)網(wǎng)站、網(wǎng)頁設(shè)計公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容