日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android之NDK开发学习总结

發布時間:2025/4/14 Android 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android之NDK开发学习总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Android之NDK開發

http://www.cnblogs.com/devinzhang/archive/2012/02/29/2373729.html


?一、NDK產生的背景


  Android平臺從誕生起,就已經支持C、C++開發。眾所周知,Android的SDK基于Java實現,這意味著


基于Android SDK進行開發的第三方應用都必須使用Java語言。但這并不等同于“第三方應用只能使用


Java”。在Android SDK首次發布時,Google就宣稱其虛擬機Dalvik支持JNI編程方式,也就是第三方應


用完全可以通過JNI調用自己的C動態庫,即在Android平臺上,“Java+C”的編程方式是一直都可以實現


的。


  不過,Google也表示,使用原生SDK編程相比Dalvik虛擬機也有一些劣勢,Android SDK文檔里,找


不到任何JNI方面的幫助。即使第三方應用開發者使用JNI完成了自己的C動態鏈接庫(so)開發,但是so


如何和應用程序一起打包成apk并發布?這里面也存在技術障礙。比如程序更加復雜,兼容性難以保障,


無法訪問Framework API,Debug難度更大等。開發者需要自行斟酌使用。


  于是NDK就應運而生了。NDK全稱是Native Development Kit。


  NDK的發布,使“Java+C”的開發方式終于轉正,成為官方支持的開發方式。NDK將是Android平臺支


持C開發的開端。


?


二、為什么使用NDK


  1.代碼的保護。由于apk的java層代碼很容易被反編譯,而C/C++庫反匯難度較大。


  2.可以方便地使用現存的開源庫。大部分現存的開源庫都是用C/C++代碼編寫的。


  3.提高程序的執行效率。將要求高性能的應用邏輯使用C開發,從而提高應用程序的執行效率。


  4.便于移植。用C/C++寫得庫可以方便在其他的嵌入式平臺上再次使用。


?


三、NDK簡介


? ? ? ?1.NDK是一系列工具的集合


? ? ? ?NDK提供了一系列的工具,幫助開發者快速開發C(或C++)的動態庫,并能自動將so和java應用


一起打包成apk。這些工具對開發者的幫助是巨大的。


NDK集成了交叉編譯器,并提供了相應的mk文件隔離CPU、平臺、ABI等差異,開發人員只需要簡單修改mk


文件(指出“哪些文件需要編譯”、“編譯特性要求”等),就可以創建出so。


NDK可以自動地將so和Java應用一起打包,極大地減輕了開發人員的打包工作。


? ? ? ?2.NDK提供了一份穩定、功能有限的API頭文件聲明


? ? ? ?Google明確聲明該API是穩定的,在后續所有版本中都穩定支持當前發布的API。從該版本的NDK


中看出,這些API支持的功能非常有限,包含有:C標準庫(libc)、標準數學庫(libm)、壓縮庫


(libz)、Log庫(liblog)。


?


四、NDK開發環境的搭建


1.下載安裝Android NDK


  地址:http://developer.android.com/sdk/ndk/index.html


2.下載安裝cygwin


  由于NDK編譯代碼時必須要用到make和gcc,所以你必須先搭建一個linux環境, cygwin是一個在


windows平臺上運行的unix模擬環境,它對于學習unix/linux操作環境,或者從unix到windows的應用程序


移植,非常有用。通過它,你就可以在不安裝linux的情況下使用NDK來編譯C、C++代碼了。下載地址:


http://www.cygwin.com


  1)然后雙擊運行吧,運行后你將看到安裝向導界面。


  2)點擊下一步,此時讓你選擇安裝方式:


Install from Internet:直接從Internet上下載并立即安裝(安裝完成后,下載好的安裝文件并不會被


刪除,而是仍然被保留,以便下次再安裝)。
Download Without Installing:只是將安裝文件下載到本地,但暫時不安裝。
Install from Local Directory:不下載安裝文件,直接從本地某個含有安裝文件的目錄進行安裝。
  3)選擇第一項,然后點擊下一步。


  4)選擇要安裝的目錄,注意,最好不要放到有中文和空格的目錄里,似乎會造成安裝出問題,其它


選項不用變,之后點下一步:


  5)上一步是選擇安裝cygwin的目錄,這個是選擇你下載的安裝包所在的目錄,默認是你運行


setup.exe的目錄,直接點下一步就可以:


  6)此時你共有三種連接方式選擇:


Direct Connection:直接連接。
Use IE5 Settings:使用IE的連接參數設置進行連接。
Use HTTP/FTP Proxy:使用HTTP或FTP代理服務器進行連接(需要輸入服務器地址、端口號)。
  用戶可根據自己的網絡連接的實情情況進行選擇,一般正常情況下,均選擇第一種,也就是直接連


接方式。然后再點擊“下一步”。


  7)這是選擇要下載的站點,選擇后點下一步。


  8)此時會下載加載安裝包列表


  9)Search是可以輸入你要下載的包的名稱,能夠快速篩選出你要下載的包。那四個單選按鈕是選擇


下邊樹的樣式,默認就行,不用動。View默認是Category,建議改成full顯示全部包再查,省的一些包


被隱藏掉。左下角那個復選框是是否隱藏過期包,默認打鉤,不用管它就行,下邊開始下載我們要安裝


的包吧,為了避免全部下載,這里列出了后面開發NDK用得著的包:autoconf2.1、automake1.10、


binutils、gcc-core、gcc- g++、gcc4-core、gcc4-g++、gdb、pcre、pcre-devel、gawk、make共12個





  10)然后開始選擇安裝這些包吧,點skip,把它變成數字版本格式,要確保Bin項變成叉號,而Src


項是源碼,這個就沒必要選了。


  11)下面測試一下cygwin是不是已經安裝好了。


? ? ? 運行cygwin,在彈出的命令行窗口輸入:cygcheck -c cygwin命令,會打印出當前cygwin的版本


和運行狀 態,如果status是ok的話,則cygwin運行正常。


? ? ? 然后依次輸入gcc –version,g++ --version,make –version,gdb –version進行測試,如果


都打印出版本信息和一些描述信息,則cygwin安裝成功!


3.配置 NDK 環境變量


  a.首先找到 cygwin 的安裝目錄,找到一個 home\< 你的用戶名 >\.bash_profile 文件,我的是


:E:\cygwin\home\Administrator\.bash_profile , ( 注意:我安裝的時候我的 home 文件夾下面什


么都沒有,解決 的辦法:首先打開環境變量,把里面的用戶變量中的 HOME 變量刪掉,在 E:\cygwin


\home 文件夾下建立名為Administrator 的文件夾(是用戶名),然后把 E:\cygwin\etc\skel


\.bash_profile 拷貝到該文件夾下 ) 。


  b.打開 bash_profile 文件,添加 NDK=/cygdrive/< 你的盤符 >/<android ndk 目錄 > 例如:


      NDK=/cygdrive/e/android-ndk-r5


      export NDK


  NDK 這個名字是隨便取的,為了方面以后使用方便,選個簡短的名字,然后保存


  c.打開 cygwin ,輸入 cd $NDK ,如果輸出上面配置的 /cygdrive/e/android-ndk-r5 信息,則


表明環境變量設置成功了。


?


4.用 NDK 來編譯程序 ??


  a.現在我們用安裝好的 NDK 來編譯一個簡單的程序吧,我們選擇 ndk 自帶的例子 hello-jni ,


我的位于E:\android-ndk-r5\samples\hello-jni( 根據你具體的安裝位置而定 ) ,


  b.運行 cygwin ,輸入命令 cd /cygdrive/e/android-ndk-r5/samples/hello-jni ,進入到 E:


\android-ndk-r5\samples\hello-jni 目錄。


  c.輸入 $NDK/ndk-build ,執行成功后,它會自動生成一個 libs 目錄,把編譯生成的 .so 文件


放在里面。 ($NDK是調用我們之前配置好的環境變量, ndk-build 是調用 ndk 的編譯程序 )


  d.此時去 hello-jni 的 libs 目錄下看有沒有生成的 .so 文件,如果有,你的 ndk 就運行正常


啦!


?


5.在 eclipse 中集成 c/c++ 開發環境


  a.裝 Eclipse 的 C/C++ 環境插件: CDT ,這里選擇在線安裝。  首先登錄?


http://www.eclipse.org/cdt/downloads.php ,找到對應你 Eclipse 版本的 CDT 插件 的在線安裝地


址。


  b.然后點 Help 菜單,找到 Install New Software 菜單


  c.點擊 Add 按鈕,把取的地址填進去,出來插件列表后,選 Select All ,然后選擇下一步即可


完成安裝。


  d.安裝完成后,在 eclispe 中右擊新建一個項目,如果出現了 c/c++ 項目,則表明你的 CDT 插


件安裝成功啦!


?


6.配置 C/C++ 的編譯器


  a.打開 eclipse ,導入ndk 自帶的hello-jni 例子,右鍵單擊項目名稱,點擊 Properties ,彈


出配置界面,之后再點擊 Builders ,彈出項目的編譯工具列表,之后點擊 New,新添加一個編譯器,


點擊后出現添加界面,選擇 Program ,點擊 OK。


  b.出現了添加界面,首先給編譯配置起個名字,如: C_Builder,設置 Location 為 < 你 cygwin?


安裝路徑 >\bin\bash.exe 程序,例:E:\cygwin\bin\bash.exe ,設置Working Directory為<你?


cygwin 安裝路徑 >\bin 目錄,例如: E:\cygwin\bin,設置 Arguments 為 --login -c "cd?


/cygdrive/e/android-ndk-r5/samples/hello-jni && $NDK /ndk-build"


  上面的配置中 /cygdrive/e/android-ndk-r5/samples/hello-jni 是你當前要編譯的程序的目錄,?


$NDK 是之前配置 ?的 ndk 的環境變量,這兩個根據你具體的安裝目錄進行配置,其他的不用變,?


Arguments 這串參數實際是 ?給 bash.exe 命令行程序傳參數,進入要編譯的程序目錄,然后運行?


ndk-build 編譯程序


  c.接著切換到 Refresh 選項卡,給 Refresh resources upon completion 打上鉤


  d.然后切換到 Build Options 選項卡,勾選上最后三項


  e.之后點擊 Specify Resources 按鈕,選擇資源目錄,勾選你的項目目錄即可


  f.最后點擊 Finish,點擊 OK 一路把剛才的配置都保存下來,注意:如果你配置的編譯器在其它


編譯器下邊,記得一定要點 Up 按鈕,把它排到第一位,否則 C 代碼的編譯晚于Java代碼的編譯,會造


成你的 C 代碼要編譯兩次才能看到最新的修改。


  g.編譯配置也配置完成啦,現在來測試一下是否可以自動編譯呢,打開項目 jni 目錄里的?


hello-jni.c 文件把提示 Hello from JNI! 改成其他的文字:如: Hello , My name is alex. ,然


后再模 擬器中運行你的程序,如果模擬器中顯示了你最新修改的文字,那么 Congratulations !你已


經全部配置成功啦!


?


五、開發自己的NDK程序


  入門的最好辦法就是學習Android自帶的例子, 這里就通過學習Android的NDK自帶的demo程序:


hello-jni來達到這個目的。


1、 開發環境的搭建


  1)android的NDK開發需要在linux下進行: 因為需要把C/C++編寫的代碼生成能在arm上運行的.so文


件,這就需要用到交叉編譯環境,而交叉編譯需要在linux系統下才能完成。


  2)安裝android-ndk開發包,這個開發包可以在google android 官網下載: 通過這個開發包的工具


才能將android jni 的C/C++的代碼編譯成庫


  3)android應用程序開發環境: 包括eclipse、java、 android sdk、 adt等。


  如何下載和安裝android-ndk我這里就不啰嗦了,安裝完之后,需要將android-ndk的路勁加到環境


變量PATH中:


    sudo gedit /etc/environment


  在environment的PATH環境變量中添加你的android-ndk的安裝路勁,然后再讓這個更改的環境變量


立即生效:


     source ?/etc/environment


  經過了上述步驟,在命令行下敲:


    ndk-bulid


  彈出如下的錯誤,而不是說ndk-build not found,就說明ndk環境已經安裝成功了。


    Android NDK: Could not find application project directory ! ? ?
    Android NDK: Please define the NDK_PROJECT_PATH variable to point to it. ? ?
    /home/braincol/workspace/android/android-ndk-r5/build/core/build-local.mk:85: ***?


Android NDK: Aborting ? ?. ?Stop.


?2.代碼的編寫


  1)首先是寫java代碼


  建立一個Android應用工程HelloJni,創建HelloJni.java文件:


  HelloJni.java :


復制代碼
import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;


public class HelloJni extends Activity
{
? ? /** Called when the activity is first created. */
? ? @Override
? ? public void onCreate(Bundle savedInstanceState)
? ? {
? ? ? ? super.onCreate(savedInstanceState);


? ? ? ? TextView ?tv = new TextView(this);
? ? ? ? tv.setText( stringFromJNI() );
? ? ? ? setContentView(tv);
? ? }




? ? /* A native method that is implemented by the 'hello-jni' native library, which is?


packaged with this application. */
? ? public native String ?stringFromJNI();


? ? public native String ?unimplementedStringFromJNI();






? ? /* this is used to load the 'hello-jni' library on application startup. The library has?


already been unpacked into


? ? ? /data/data/com.example.HelloJni/lib/libhello-jni.so at installation time by the?


package manager. */
? ? static {
? ? ? ? System.loadLibrary("hello-jni");
? ? }
}
復制代碼
  這段代碼很簡單,注釋也很清晰,這里只提兩點::


static{?
System.loadLibrary("hello-jni");?
}
  表明程序開始運行的時候會加載hello-jni, static區聲明的代碼會先于onCreate方法執行。如果你


的程序中有多個類,而且如果HelloJni這個類不是你應用程序的入口,那么hello-jni(完整的名字是


libhello-jni.so)這個庫會在第一次使用HelloJni這個類的時候加載。


public native String stringFromJNI();?
public native String unimplementedStringFromJNI();
  可以看到這兩個方法的聲明中有 native 關鍵字, 這個關鍵字表示這兩個方法是本地方法,也就是


說這兩個方法是通過本地代碼(C/C++)實現的,在java代碼中僅僅是聲明。


  用eclipse編譯該工程,生成相應的.class文件,這步必須在下一步之前完成,因為生成.h文件需要


用到相應的.class文件。


2)編寫相應的C/C++代碼


  剛開始學的時候,有個問題會讓人很困惑,相應的C/C++代碼如何編寫,函數名如何定義? 這里講


一個方法,利用javah這個工具生成相應的.h文件,然后根據這個.h文件編寫相應的C/C++代碼。


  a. 生成相應.h文件:


  就拿我這的環境來說,首先在終端下進入剛剛建立的HelloJni工程的目錄:


braincol@ubuntu:~$ cd workspace/android/NDK/hello-jni/
  ls查看工程文件  


braincol@ubuntu:~/workspace/android/NDK/hello-jni$ ls?
AndroidManifest.xml ?assets ?bin ?default.properties ?gen ?res ?src?
  可以看到目前僅僅有幾個標準的android應用程序的文件(夾)。


  首先我們在工程目錄下建立一個jni文件夾:


braincol@ubuntu:~/workspace/android/NDK/hello-jni$ mkdir jni?
braincol@ubuntu:~/workspace/android/NDK/hello-jni$ ls?
AndroidManifest.xml ?assets ?bin ?default.properties ?gen ?jni ?res ?src?
  下面就可以生成相應的.h文件了:


braincol@ubuntu:~/workspace/android/NDK/hello-jni$ javah -classpath bin -d jni?


com.example.hellojni.HelloJni?
  -classpath bin:表示類的路勁


  -d jni: 表示生成的頭文件存放的目錄


  com.example.hellojni.HelloJni 則是完整類名


  這一步的成功要建立在已經在 bin/com/example/hellojni/ ?目錄下生成了 HelloJni.class的基礎


之上。現在可以看到jni目錄下多了個.h文件:


braincol@ubuntu:~/workspace/android/NDK/hello-jni$ cd jni/?
braincol@ubuntu:~/workspace/android/NDK/hello-jni/jni$ ls?
com_example_hellojni_HelloJni.h
  我們來看看com_example_hellojni_HelloJni.h的內容:


  com_example_hellojni_HelloJni.h :


復制代碼
/* DO NOT EDIT THIS FILE - it is machine generated */


#include <jni.h>


/* Header for class com_example_hellojni_HelloJni */


#ifndef _Included_com_example_hellojni_HelloJni


#define _Included_com_example_hellojni_HelloJni


#ifdef __cplusplus


extern "C" {


#endif


/*


?* Class: ? ? com_example_hellojni_HelloJni


?* Method: ? ?stringFromJNI


?* Signature: ()Ljava/lang/String;


?*/


JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI


? (JNIEnv *, jobject);




/*


?* Class: ? ? com_example_hellojni_HelloJni


?* Method: ? ?unimplementedStringFromJNI


?* Signature: ()Ljava/lang/String;


?*/


JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_unimplementedStringFromJNI


? (JNIEnv *, jobject);




#ifdef __cplusplus


}


#endif


#endif
復制代碼
  上面代碼中的JNIEXPORT 和 JNICALL 是jni的宏,在android的jni中不需要,當然寫上去也不會有


錯。從上面的源碼中可以看出這個函數名那是相當的長啊。。。。 不過還是很有規律的, 完全按照:


java_pacakege_class_mathod 形式來命名。


  也就是說:


  Hello.java中 stringFromJNI() 方法對應于 C/C++中的?


Java_com_example_hellojni_HelloJni_stringFromJNI() 方法


  HelloJni.java中的 unimplementedStringFromJNI() 方法對應于 C/C++中的?


Java_com_example_hellojni_HelloJni_unimplementedStringFromJNI() 方法?


  注意下其中的注釋:


  Signature: ()Ljava/lang/String;?


  ()Ljava/lang/String;()表示函數的參數為空(這里為空是指除了JNIEnv *, jobject 這兩個參數


之外沒有其他參數,JNIEnv*, jobject是所有jni函數必有的兩個參數,分別表示jni環境和對應的java


類(或對象)本身),Ljava/lang/String; 表示函數的返回值是java的String對象。


?


b. 編寫相應的.c文件:


  hello-jni.c :


復制代碼
#include <string.h>
#include <jni.h>




/* This is a trivial JNI example where we use a native method


?* to return a new VM String. See the corresponding Java source


?* file located at:


?* ? apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java


?*/


jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
{
? ? return (*env)->NewStringUTF(env, "Hello from JNI !");
}
復制代碼
  這里只是實現了Java_com_example_hellojni_HelloJni_stringFromJNI方法,而?


Java_com_example_hellojni_HelloJni_unimplementedStringFromJNI 方法并沒有實現,因為在


HelloJni.java中只調用了stringFromJNI()方法,所以unimplementedStringFromJNI()方法沒有實現也


沒關系,不過建議最好還是把所有java中定義的本地方法都實現了,寫個空函數也行啊。。。有總比沒


有好。


  Java_com_example_hellojni_HelloJni_stringFromJNI() 函數只是簡單的返回了一個內容為?


"Hello from JNI !" 的jstring對象(對應于java中的String對象)。hello-jni.c文件已經編寫好了,


現在可以把com_example_hellojni_HelloJni.h文件給刪了,當然留著也行,只是我還是習慣把不需要的


文件給清理干凈了。


?


3)編譯hello-jni.c 生成相應的庫


a 編寫Android.mk文件


  在jni目錄下(即hello-jni.c 同級目錄下)新建一個Android.mk文件,Android.mk 文件是Android?


的 makefile文件,內容如下:


復制代碼
# Copyright (C) 2009 The Android Open Source Project


#


# Licensed under the Apache License, Version 2.0 (the "License");


# you may not use this file except in compliance with the License.


# You may obtain a copy of the License at


#


# ? ? ?http://www.apache.org/licenses/LICENSE-2.0


#


# Unless required by applicable law or agreed to in writing, software


# distributed under the License is distributed on an "AS IS" BASIS,


# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.


# See the License for the specific language governing permissions and


# limitations under the License.


#


LOCAL_PATH := $(call my-dir)






include $(CLEAR_VARS)






LOCAL_MODULE ? ?:= hello-jni


LOCAL_SRC_FILES := hello-jni.c






include $(BUILD_SHARED_LIBRARY)
復制代碼




  這個Androd.mk文件很短,下面我們來逐行解釋下:


    LOCAL_PATH := $(call my-dir)


  一個Android.mk 文件首先必須定義好LOCAL_PATH變量。它用于在開發樹中查找源文件。在這個例子


中,宏函數’my-dir’, 由編譯系統提供,用于返回當前路徑(即包含Android.mk file文件的目錄)。


    include $( CLEAR_VARS)


  CLEAR_VARS由編譯系統提供,指定讓GNU MAKEFILE為你清除許多LOCAL_XXX變量(例如?


LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等...), 除LOCAL_PATH 。這是必要的


,因為所有的編譯控制文件都在同一個GNU MAKE執行環境中,所有的變量都是全局的。


    LOCAL_MODULE := hello-jni


  編譯的目標對象,LOCAL_MODULE變量必須定義,以標識你在Android.mk文件中描述的每個模塊。名


稱必須是唯一的,而且不包含任何空格。


注意:編譯系統會自動產生合適的前綴和后綴,換句話說,一個被命名為'hello-jni'的共享庫模塊,將


會生成'libhello-jni.so'文件。


  重要注意事項:如果你把庫命名為‘libhello-jni’,編譯系統將不會添加任何的lib前綴,也會生


成 'libhello-jni.so',這是為了支持來源于Android平臺的源代碼的Android.mk文件,如果你確實需要


這么做的話。


    LOCAL_SRC_FILES := hello-jni.c


  LOCAL_SRC_FILES變量必須包含將要編譯打包進模塊中的C或C++源代碼文件。注意,你不用在這里列


出頭文件和包含文件,因為編譯系統將會自動為你找出依賴型的文件;僅僅列出直接傳遞給編譯器的源


代碼文件就好。


  注意,默認的C++源碼文件的擴展名是’.cpp’. 指定一個不同的擴展名也是可能的,只要定義


LOCAL_DEFAULT_CPP_EXTENSION變量,不要忘記開始的小圓點(也就是’.cxx’,而不是’cxx’)


    include $(BUILD_SHARED_LIBRARY)


  BUILD_SHARED_LIBRARY表示編譯生成共享庫,是編譯系統提供的變量,指向一個GNU Makefile腳本


,負責收集自從上次調用'include $(CLEAR_VARS)'以來,定義在LOCAL_XXX變量中的所有信息,并且決


定編譯什么,如何正確地去做。還有 BUILD_STATIC_LIBRARY變量表示生成靜態庫:lib


$(LOCAL_MODULE).a, BUILD_EXECUTABLE 表示生成可執行文件。


?


b. 生成.so共享庫文件


  Andro文件已經編寫好了,現在可以用android NDK開發包中的 ndk-build腳本生成對應的.so共享庫


了,方法如下:


    braincol@ubuntu:~/workspace/android/NDK/hello-jni/jni$ cd ..?
    braincol@ubuntu:~/workspace/android/NDK/hello-jni$ ls?
    AndroidManifest.xml ?assets ?bin ?default.properties ?gen ?jni ?libs ?obj ?res ?src?
    braincol@ubuntu:~/workspace/android/NDK/hello-jni$ ndk-build?
    Gdbserver ? ? ?: [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver?
    Gdbsetup ? ? ? : libs/armeabi/gdb.setup?
    Install ? ? ? ?: libhello-jni.so => libs/armeabi/libhello-jni.so?


  可以看到已經正確的生成了libhello-jni.so共享庫了, 我們去 libs/armeabi/ 目錄下看看:


    braincol@ubuntu:~/workspace/android/NDK/hello-jni$ cd libs/?
    braincol@ubuntu:~/workspace/android/NDK/hello-jni/libs$ ls?
    armeabi?
    braincol@ubuntu:~/workspace/android/NDK/hello-jni/libs$ cd armeabi/?
    braincol@ubuntu:~/workspace/android/NDK/hello-jni/libs/armeabi$ ls?
    gdbserver ?gdb.setup ?libhello-jni.so


4)在eclipse重新編譯HelloJni工程,生成apk


  eclipse中刷新下HelloJni工程,重新編譯生成apk,libhello-jni.so共享庫會一起打包在apk文件


內。在模擬器中看看運行結果。


?


參考資料:


http://blog.csdn.net/hhao137/article/details/4304664


http://www.cnblogs.com/hibraincol/archive/2011/05/30/2063847.html


http://yueguc.iteye.com/blog/946724


http://www.cnblogs.com/hibraincol/archive/2011/05/30/2063847.html
========

Android NDK 概述

Android NDK 是在SDK前面又加上了“原生”二字,即Native Development Kit,因此又被Google稱為“


NDK”。
眾所周知,Android程序運行在Dalvik虛擬機中,NDK允許用戶使用類似C / C++之類的原生代碼語言執行


部分程序。
NDK包括了:
從C / C++生成原生代碼庫所需要的工具和build files。
將一致的原生庫嵌入可以在Android設備上部署的應用程序包文件(application packages files ,


即.apk文件)中。
支持所有未來Android平臺的一系列原生系統頭文件和庫
為何要用到NDK?
概括來說主要分為以下幾種情況:
1. 代碼的保護,由于apk的java層代碼很容易被反編譯,而C/C++庫反匯難度較大。
2. 在NDK中調用第三方C/C++庫,因為大部分的開源庫都是用C/C++代碼編寫的。
3. 便于移植,用C/C++寫的庫可以方便在其他的嵌入式平臺上再次使用。
========

Android NDK環境搭建與簡單實例

http://www.2cto.com/kf/201505/403121.html


一、NDK與JNI簡介


NDK全稱為native development kit本地語言(C&C++)開發包。而對應的是經常接觸的Android-SDK,(


software development kit)軟件開發包(只支持java語言開發)。


簡單來說利用NDK,可以開發純C&C++的代碼,然后編譯成庫,讓利用Android-SDK開發的Java程序調用。


NDK開發的可以稱之為底層開發或者jni(java native interface)層開發,SDK開發可以稱為上層開發





Android開發中使用NDK的原因:


1、眾所周知,利用SDK編寫的代碼,生成的APK,很容易就可以反編譯了,安全性極為不高,而利用NDK


開發的庫,不容易被反編譯,保密性,安全性都提高了。


2、很多開源工程和大型工程都是C&C++代碼,把它們轉換為純java語言顯然是不可能的。


3、C&C++的代碼運行速度和效率都比java快很多。


JNI全稱為Java Native Interface(JAVA本地調用)。從Java1.1開始,JNI成為java平臺的一部分,它


允許Java代碼和其他語言寫的代碼(如C&C++)進行交互。并非從Android發布才引入JNI的概念的。


簡單來說,Android的NDK提供了一些交叉編譯工具鏈和Android自帶的庫,這些Android的庫可以讓開發


者在編寫本地語言的程序時調用。而NDK提供的交叉編譯工具鏈就對已經編寫好的C&C++代碼進行編譯,


生成庫。當然了,你也可以自己搭建交叉編譯環境,而不用NDK的工具和庫。然后生成庫,只要規范操作


,一樣可以生成能讓JAVA層成功調用的庫文件的。
二、NDK環境搭建


使用最新NDK,直接拋棄cygwin,以前做Android的項目要用到NDK就必須要下載NDK,下載安裝Cygwin(模


擬Linux環境用的),下載CDT(Eclipse C/C++開發插件),還要配置編譯器,環境變量,特別麻煩,新


版就不需要了。


下載Android SDK http://developer.android.com/sdk/index.html


下載Android NDK http://developer.android.com/tools/sdk/ndk/index.html (注:NDK版本在r7以上


之后就集成了Cygwin,而且還是十分精簡版。)




本人使用的SDK和NDK為


Eclipse配置


打開Eclipse,點Window->Preferences->Android->NDK,設置NDK路徑,例如我的是F:android-ndk-r10e


。新建一個Android工程NDKTest,在工程上右鍵點擊Android Tools->Add Native Support...,然后給我


們的.so文件取個名字(默認已經起好了,就是包名NDKTest)。這時候工程就會多一個jni的文件夾,


jni下有Android.mk和NDKTest.cpp文件。Android.mk是NDK工程的Makefile,NDKTest.cpp就是NDK的源文


件。\接下來編寫NDKTest.cpp文件


<span style="font-size:14px;">#include <jni.h>
#include <string.h>
extern C
?
jstring Java_com_example_ndktest_MainActivity_NDKTestFromJNI(JNIEnv* env,
? ? ? ? jobject thiz) {
? ? return env->NewStringUTF(Hello from JNI !);
}
</string.h></jni.h></span>
繼續編寫MainActivity.java文件


<span style="font-size:14px;">package com.example.ndktest;
?
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
?
public class MainActivity extends Activity {
?
? ? protected void onCreate(Bundle savedInstanceState) {
? ? ? ? super.onCreate(savedInstanceState);
?
? ? ? ? TextView tv = new TextView(this);
? ? ? ? tv.setText(NDKTestFromJNI());
? ? ? ? setContentView(tv);
? ? }
?
? ? public native String NDKTestFromJNI();// native聲明,表示這個方法來自Native層。實現過程


已經在native層實現了
?
? ? static {
? ? ? ? System.loadLibrary(NDKTest);// 加載庫,前面的lib和后綴名不用寫
? ? }
}
</span>
編譯運行,先編譯cpp文件,右擊工程項目NDKTest,Build Project,成功結果在libs目錄下生成了.so


文件\\


然后編譯Android Java工程,右擊工程項目run application,部署到真機上的結果\


三、相關問題


NDK搭建與實例過程中,遇到的一些問題如下:


Eclipse報錯“Unresolved inclusion jni.h”
在做NDK開發過程中有時候在eclipse里會遇到其無法處理inclusion導致symbol顯示錯誤,網上有許多方


法可以解決類似“Unresolved inclusion jni.h” 錯誤的方法,包括includepath等方法,不過對我都


不管用。


最終的解決辦法就是初始化eclipse對該project的nativesupport:


1. 在eclipse中關閉指定Project


2. 用其他編輯工具打開該project的.project文件,刪除以下內容:


......


org.eclipse.cdt.managedbuilder.core.genmakebuilder
clean,full,incremental,


......


org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
full,incremental,


?......


org.eclipse.cdt.core.cnature
org.eclipse.cdt.core.ccnature
org.eclipse.cdt.managedbuilder.core.managedBuildNature
org.eclipse.cdt.managedbuilder.core.ScannerConfigNature


3. 刪除.cproject文件


4. 在eclipse里打開原來的project, refresh,然后右鍵->properties->Android Tools -> Add?


Native Support


5. 搞定


window平臺下 Eclipse Ndk開發中的Method 'NewStringUTF' could not be resolved問題
?
項目右鍵->屬性->c/c++常規->Code Analysis,選擇Use project settings 中的方法無法被解析


(Method cannot be resolved)取消選擇,應用->確定,然后刷新、清理、刷新、build項目。


?
jni/hellocpp/main.cpp:16:18:error: base operand of '->' has non-pointer type 'JNIEnv {aka?


_JNIEnv}'
?


錯誤在于:


(*env)->NewStringUTF(env, Hello from JNI !);


這一行,這是c的寫法,而我的是cpp程序,需要改寫成:


env->NewStringUTF( Hello from JNI !);


java.lang.UnsatisfiedLinkError:Native method not found問題
?


1、c++中的方法Java_xxx_xxx中的Java 首字母一定要大寫


2、如果是 .cpp 文件則用 extern C {您的方法在這里},大括號里是您的本地方法。
========

總結

以上是生活随笔為你收集整理的Android之NDK开发学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 9久精品| 毛片网站有哪些 | 亚洲精品v天堂中文字幕 | 四虎影院成人 | 人人澡人人添 | 国产精品视频麻豆 | 国语对白一区 | 国产欧美一区二区三区视频 | 亚洲激情视频在线播放 | 亚洲五月花 | 亚洲精选久久 | 成人a在线 | 四虎av网站 | 天天搞天天干 | 国产成人在线一区 | 天堂在线中文网 | 国产精品正在播放 | 日本三级一区二区 | 欧美综合在线视频 | 欧美激情二区三区 | 色综合天天操 | 国产成人啪一区二区 | 久久久人妻无码一区二区 | 懂色av一区二区三区免费观看 | www国产成人| 亚洲一区二区三区三州 | 亚洲第一免费视频 | 国产精品 色 | 人妻 日韩精品 中文字幕 | 露胸app| 黄色大片网站 | 最近免费中文字幕 | 超碰在线观看av | 日本精品黄| 艳情五月 | 一级片在线视频 | 日韩欧美精品在线视频 | 欧美日韩高清一区 | 男生女生插插插 | 亚洲精品久久久久avwww潮水 | 欧美劲爆第一页 | 三级在线看中文字幕完整版 | 日本伊人影院 | 波多野结衣a级片 | 激情小说综合 | 欧美三级韩国三级日本三斤 | 亚洲av成人无码久久精品 | 国产精品白嫩极品美女视频 | 91在线视频导航 | 日穴视频| 91福利在线观看视频 | 欧美一区二区不卡视频 | 成人无码视频 | 91成人天堂久久成人 | 欧美日韩一区二区综合 | 好吊色这里只有精品 | 欧美精品一区二区成人 | 久久久18禁一区二区三区精品 | 成人毛片视频免费看 | 免费美女av | 美女脱了内裤喂我喝尿视频 | 韩国三级在线看 | 国产精品高清无码在线观看 | 在线色亚洲 | 九九视频免费 | jlzzjlzz国产精品久久 | 久久久久亚洲国产 | 欧美日韩国产精品 | 久久免费在线视频 | 91香蕉在线视频 | a√国产 | 久久影院精品 | 91亚洲精 | 少妇人妻在线视频 | 极品美妇后花庭翘臀娇吟小说 | 黄在线免费 | 老司机午夜免费精品视频 | 国产xxxxwwww | 国产三级第一页 | 男人操女人动态图 | a一级视频 | 欧美xxxx黑人又粗又长密月 | 国产精品电影网 | 欧美v日本 | 国产精品一色哟哟哟 | 色屁屁影院www国产高清麻豆 | 国产一区二区三区在线播放无 | 中国女人裸体乱淫 | 青青青青操 | 国产视频中文字幕 | 一乃葵在线| 91久久在线观看 | 好男人影视www | 91色交视频| 天天做天天干 | 国产中文字幕乱人伦在线观看 | 成人黄色片免费看 | 国产操视频 | 在线观看的av |