Android native应用开发简明教程 (1) - 本地开发武器库概览

简介: native应用比起Java应用来,跟Android版本的相关性更高一些。 所以,这些API都是根据平台版本号分成不同的目录的。 我们来看看Android为我们提供了哪些API

Android本地开发武器库概览

Android本地开发支持简史

Android 1.0的时代,没有提供对于C/C++开发本地Android代码的支持,尽管Android系统本身使用了大量的C++做底层开发。

第一个里程碑 - 支持jni开发so库 (Android 1.5)

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)

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="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:hasCode="false">

    <!-- Our activity is the built-in NativeActivity framework class.
         This will take care of integrating with our NDK code. -->
    <activity android:name="android.app.NativeActivity"
              android:label="@string/app_name"
              android:configChanges="orientation|keyboardHidden">
      <!-- Tell NativeActivity the name of our .so -->
      <meta-data android:name="android.app.lib_name"
                 android:value="native-activity" />
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
  </application>

</manifest>

因为我们没有写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_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: 辅助类

资源管理类

  • android/asset_manager.h

    • AAssetManager结构
    • AAssetDir结构
    • AAsset结构
  • android/asset_manager_jni.h

    • AAssetManager_fromJava结构

位图类

  • bitmap.h

    • AndroidBitmapInfo结构

配置类

  • configuration.h

    • AConfiguration结构

输入类

  • input.h

    • AInputEvent结构
    • AInputQueue结构
  • keycodes.h:定义了键码的enum

Looper类

  • android/looper.h

    • ALooper结构
    • ALooper_callbackFunc结构

存储类

  • android/storage_manager.h

    • AStorageManager结构
    • AStorageManager_obbCallbackFunc结构
  • android/obb.h

    • AObbInfo结构

传感器类

  • android/sensor.h

    • ASensorVector结构
    • AMetaDataEvent结构
    • AUncalibratedEvent结构
    • AHeartRateEvent结构
    • ADynamicSensorEvent结构
    • AAdditionalInfoEvent结构
    • ASensorEvent结构
目录
相关文章
|
10月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1754 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
10月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1124 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
10月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
1202 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
11月前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
935 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
|
10月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
443 0
|
11月前
|
Java 开发工具 Maven
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
1391 6
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
5950 77
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
717 11
|
移动开发 Java 编译器
Kotlin与Jetpack Compose:Android开发生态的演进与架构思考
本文从资深Android工程师视角深入分析Kotlin与Jetpack Compose在Android系统中的技术定位。Kotlin通过空安全、协程等特性解决了Java在移动开发中的痛点,成为Android官方首选语言。Jetpack Compose则引入声明式UI范式,通过重组机制实现高效UI更新。两者结合不仅提升开发效率,更为跨平台战略和现代架构模式提供技术基础,代表了Android开发生态的根本性演进。
560 0
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
517 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡

热门文章

最新文章