WIN7+64位+ndk配置
想學ndk,不知道ndk是什麼?有Android開發經驗的都知道jdk,sdk.好了其實他們三個處於同一等級,你怎麼理解jdk,sdk就怎麼理解ndk,當然它們各有各的作用
一、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環境配置
下載android-ndk-r9c解壓到相應目錄(我的 E:\adt\android-ndk-r9c)
開啟我們的eclipse(含有adt外掛的安卓開發環境)->window->preference->android->ndk設定ndk路徑apply->ok
建立JNITest應用程式右鍵單擊專案->Android Tools->Add Native Support...然後給我們的.so檔案取名,例如jni-test
這時候工程就會多一個jni的資料夾,jni下有Android.mk和jni-test.cpp檔案。Android.mk是NDK工程的Makefile,my-ndk.cpp就是NDK的原始檔。
好了專案建立成功,剩下的就是jni-test.cpp裡面的C語言程式碼實現和activity裡面JAVA程式碼實現
入門的最好辦法就是學習Android自帶的例子,
這裡就通過學習Android的NDK自帶的demo程式:hello-jni來達到這個目的。
五、把專案匯入到環境編譯執行
在NDKr7開始,google的windos版NDK提供了一個ndk-build.cmd的指令碼,這樣就可以直接利用這個指令碼編譯,而不需要cygwin了。
1,選擇你的android工程,右擊->Properties->Builders->new,新新增一個編譯器,點選之後出現新增介面,選擇Program,點選ok。
2,出現了新增介面,我們先給編譯器設定名稱,如XXX_builder。設定Location為<NDK安裝目錄>\ndk-build.cmd
設定Working Directory為${workspace_loc:/專案名稱}
4,切換到Build
Options選項卡,勾選上最後三項。再點選Specify
Resource按鈕,選擇你的android工程的
5,在編譯工具列表,我們最好將我們新建的編譯器置頂。選中點選Up按鈕置頂ok.
編譯後
hello-jni.c
/*
* 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.
*
*/
#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 )
{
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#define ABI "armeabi-libhello-jni.so/NEON"
#else
#define ABI "armeabi-libhello-jni.so"
#endif
#else
#define ABI "armeabi"
#endif
#elif defined(__i386__)
#define ABI "x86"
#elif defined(__mips__)
#define ABI "mips"
#else
#define ABI "unknown"
#endif
return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");
}
HelloJni.java
/*
* 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.
*/
package com.example.hellojni;
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);
/* Create a TextView and set its content.
* the text is retrieved by calling a native
* function.
*/
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();
/* This is another native method declaration that is *not*
* implemented by 'hello-jni'. This is simply to show that
* you can declare as many native methods in your Java code
* as you want, their implementation is searched in the
* currently loaded native libraries only the first time
* you call them.
*
* Trying to call this function will result in a
* java.lang.UnsatisfiedLinkError exception !
*/
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");
}
}
右鍵專案run as->android application