Android 1.0的時代,沒有提供對于C/C++開發本地Android代碼的支持,盡管Android系統本身使用了大量的C++做底層開發。
Android第一次支持本地開發是在Android 1.5版本,對應Android API level 3。這一版本,有了正式的Android NDK的支持,可以通過jni寫so庫的方式,供Android應用來調用。
Android 1.6增加了對于OpenGL ES 1.x的支持 Android 2.0開始支持OpenGL ES 2.0
Android 2.3是一個重要的版本,這一版本增加了完全用C++寫本地應用的接口。
我們看看這一版提供了什么API頭文件: * native_activity.h * looper.h * input.h * keycodes.h * sensor.h * rect.h * window.h * native_window.h * native_window_jni.h * configuration.h * asset_manager.h * storage_manager.h * obb.h
直至今天,Android 7.0,API level 24的時代,上面這些仍然構成了我們這系列教程的主要內容。
同時,Android 2.3還開始支持EGL接口。
Android 4.0開始支持OpenMAX AL庫。
Android 4.3開始支持Open GL ES 3.0版
Android 6.0開始支持trace庫
Android 7.0開始支持Vulkan, Camera, Choreographer和Multinework庫,同時對Open GL ES 3.2的支持
首先,寫native應用需要一個本地應用的框架的支持。 java應用需要寫一個manifest.xml,我們也入鄉隨俗需要寫一個,我們先看一個NDK sample的例子:
<?xml version="1.0" encoding="utf-8"?><!-- BEGIN_INCLUDE(manifest) --><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.native_activity" android:versionCode="1" android:versionName="1.0"> <!-- This .apk has no Java code itself, so set hasCode to false. --> <application android:allowBackup="false" android:fullBackupContent="false" android:icon="@m因為我們沒有寫Java代碼,所以需要將android:hasCode值設為false.可以使用NDK中的android_native_app_glue定義的類來對本地API進行封裝,我們來看一下,先認識一下后面我們會介紹的幾個類:
struct android_app { // The application can place a pointer to its own state object // here if it likes. void* userData; // Fill this in with the function to PRocess main app commands (APP_CMD_*) void (*onAppCmd)(struct android_app* app, int32_t cmd); // Fill this in with the function to process input events. At this point // the event has already been pre-dispatched, and it will be finished upon // return. Return 1 if you have handled the event, 0 for any default // dispatching. int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event); // The ANativeActivity object instance that this app is running in. ANativeActivity* activity; // The current configuration the app is running in. AConfiguration* config; // This is the last instance's saved state, as provided at creation time. // It is NULL if there was no state. You can use this as you need; the // memory will remain around until you call android_app_exec_cmd() for // APP_CMD_RESUME, at which point it will be freed and savedState set to NULL. // These variables should only be changed when processing a APP_CMD_SAVE_STATE, // at which point they will be initialized to NULL and you can malloc your // state and place the information here. In that case the memory will be // freed for you later. void* savedState; size_t savedStateSize; // The ALooper associated with the app's thread. ALooper* looper; // When non-NULL, this is the input queue from which the app will // receive user input events. AInputQueue* inputQueue; // When non-NULL, this is the window surface that the app can draw in. ANativeWindow* window; // Current content rectangle of the window; this is the area where the // window's content should be placed to be seen by the user. ARect contentRect; // Current state of the app's activity. May be either APP_CMD_START, // APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below. int activityState; // This is non-zero when the application's NativeActivity is being // destroyed and waiting for the app thread to complete. int destroyRequested; // ------------------------------------------------- // Below are "private" implementation of the glue code. pthread_mutex_t mutex; pthread_cond_t cond; int msgread; int msgwrite; pthread_t thread; struct android_poll_source cmdPollSource; struct android_poll_source inputPollSource; int running; int stateSaved; int destroyed; int redrawNeeded; AInputQueue* pendingInputQueue; ANativeWindow* pendingWindow; ARect pendingContentRect;};我們看下這個結構中都用到了什么: * ANativeActivity: 它是本地應用中對應于android.app.NativeActivity的代理類,定義于android/native_activity.h * AConfiguration: 處理配置項。定義于android/configuration.h * ALooper: 對應于Java中的Looper,用于處理消息隊列,每個線程只能有一個. 定義于android/looper.h * AInputQueue: 輸入事件的隊列,定義于android/input.h中 * ANativeWindow: 處理窗口的類,定義于android/native_window.h中 * ARect:代表一個矩形,定義于android/rect.h中
native應用比起Java應用來,跟Android版本的相關性更高一些。 所以,這些API都是根據平臺版本號分成不同的目錄的。 下面介紹的android下面的API,對應于Android源碼中的frameworks/native/include/中。 在NDK中,以r13b為例,Android 7.0,也就是API 24的頭文件位于:android-ndk/r13b/platforms/android-24/arch-arm64/usr/include/中。 我們首先通過一張圖來看看Android為我們提供了哪些API:

主要包括下面的頭文件: * android/native_activity.h * ANativeActivity結構:對應android.app.NativeActivity * ANativeActivityCallback結構,處理回調 * android/native_window.h * ANativeWindow結構 * ANativeWindow_Buffer結構 * android/rect.h * ARect結構:有left, top, right, bottom四個屬性的矩陣的抽象 * android/native_window_jni.h: 輔助類 * android/window.h: 輔助類
新聞熱點
疑難解答