編輯:關於Android編程
之前在進行cocos2dx開發時,已經詳細介紹了如何將win32的c++代碼移植到Android平台,當再次回顧時,發現一些基礎的東西理解並不是很徹底,今天使用Android NDK提供的一個例子做一個簡單的移植。在進行該demo前,請確認你已經配置了Android開發環境和安裝了最新的Android NDK。
創建一個Android項目 , 包名是com.example.hellojni,創建一個Activity作為程序進入的Acitivity,命名為HelloJni。
創建一個C文件,放一個函數,該函數的作用是獲取當前cpu架構並以字符串的形式返回。請注意該函數的格式: Java_包名的下劃線連接_Java文件名_java函數名。
#include#include 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-v7a/NEON" #else #define ABI "armeabi-v7a" #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 "."); }
在該Android項目的根目錄(即AndroidManifest.xml文件所在目錄)下創建一個文件夾,命名為jni(注意,文件名不能寫錯哦)
在jni目錄下,創建Android.mk和Application.mk兩個文件,同時將C文件也放進jni文件夾下面來。如下:
vcWxvqOsy/y1xNPvt6jU2jogTkRLsLLXsMS/wrwvZG9jcy9BTkRST0lELU1LLmh0bWyjrM/CzsS0+sLr0rK21NK70Km7+bG+yvTQ1MztvNPBy9eiys2hozwvcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">#返回當前文件在系統中的路徑,mk文件開始時必須定義該變量 LOCAL_PATH := $(call my-dir) #CLEAR_VARS 變量由構建系統提供,因為有大量的全局變量,在本次構建前,清除上一次的 include $(CLEAR_VARS) #LOCAL_MODULE 實際是項目名,用於區分各個項目,名字必須是唯一的而且不包含空格,最終的so庫,命名也會是 lib項目名.so LOCAL_MODULE := hello-jni #要編譯的c or cpp文件,注意不需要在這裡列舉頭文件或者include的文件,構建系統會自動幫你依賴這些文件 LOCAL_SRC_FILES := hello-jni.c #構建系統提供的變量 include $(BUILD_SHARED_LIBRARY)
Application.mk文件實際上是對應用程序本身描述的文件,它定義了應用程序需要的功能模塊的列表、針對不同cpu架構打包不同的so]、要構建release或者debug包等。
APP_ABI := XXX,這裡的XXX就是指不同的平台,可以選填的有x86,armeabi,armeabi-v7a,mips,all,值得一提的是,選擇all,則會構建出所有平台的so,如果不填該項,默認構建為armeabi的。同時,作者也做過一個實驗,構建armeabi平台的so是可以運行在intel x86架構cpu平台的,但是構建x86平台的so則不能在armeabi平台上運行的,這樣看來,應該是intel針對armeabi做了兼容,但是如果想要so 以最小的能耗運行在intel x86平台,還是要指定構建的so為x86平台。
在當前Android項目的根目錄下,運行 NDK安裝路徑/ndk-build,則開始打包so。
另外,如果運行 NDK安裝路徑/ndk-build clean,會clean當前所有的so;
運行 NDK安裝路徑/ndk-build -B V=1,則強制重新打包,
如果想要打包多個so,則可以在Android.mk定義多個modules,或者寫多個Android.mk,每個Android.mk定義一個modules,我這裡在jni目錄下又創建了一個nick文件夾,用於放置新的C文件。
此時,只需要改動jni目錄下的Android.mk,再次對nick文件夾的C代碼打包即可。jni下的Android.mk文件:
#返回當前文件在系統中的路徑,mk文件開始時必須定義該變量 LOCAL_PATH := $(call my-dir) #CLEAR_VARS 變量由構建系統提供,因為有大量的全局變量,在本次構建前,清除上一次的 include $(CLEAR_VARS) #LOCAL_MODULE 實際是項目名,用於區分各個項目,名字必須是唯一的而且不包含空格,最終的so庫,命名也會是 lib項目名.so LOCAL_MODULE := hello-jni #要編譯的c or cpp文件,注意不需要在這裡列舉頭文件或者include的文件,構建系統會自動幫你依賴這些文件 LOCAL_SRC_FILES := hello-jni.c #構建系統提供的變量 include $(BUILD_SHARED_LIBRARY) #對nick文件夾下的代碼打包so include $(CLEAR_VARS) LOCAL_MODULE := hello-jni-mine LOCAL_SRC_FILES := nick/hello-jni.c include $(BUILD_SHARED_LIBRARY)是的,你沒看錯,重新加上LOCAL_MODULE和LOCAL_SRC_FILES變量重新配置一下即可。
在Activity中,我們使用static 關鍵詞將加載so放在函數體中,以保證直接先加載so.
static { System.loadLibrary("hello-jni"); }要注意的是,System.loadLibrary()中填寫的並不是完整的so名,而是去掉前綴lib和後綴.so的,也就是Android.mk中的LOCAL_MODULE變量。
java層的函數要用native關鍵詞聲明這次調用native層的函數,如果該java函數是public native String XXXX(),那麼在這裡就是調用C代碼中的Java_com_example_hellojni_HelloJni_stringFromJNI()函數。
以上就是Android平台打包so和調用的一個最基本的demo,其實整個流程還是比較簡單的,有一些規定的命名是不能隨便修改的,如果jni文件夾名,Android.mk,Application.mk文件名,被java層調用的C函數命名等,這些都是有規則的。
問題一、android系統支持什麼字體庫?1、Android系統默認支持三類字體家族,分別為:“serif”,“sans-serif&
前段時間跟同學聊天,說道他們公司准備將開發環境從Windows遷移到Linux上,突然想到還沒試過在Linux上搭建Android開發環境,趁著有空試一下,百度發現,網上
引言Service服務是Android四大組件之一,在Android中有著舉足重輕的作用。Service服務是工作的UI線程中,當你的應用需要下載一個文件或者播放音樂等長
進度條(ProgressBar)java.lang.Object;android.view.View;android.widget.ProgressBar;Progres