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结构
目录
相关文章
|
20天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
41 19
|
20天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
46 14
|
23天前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
21天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
在数字时代,掌握安卓应用开发技能是进入IT行业的关键。本文将引导读者从零基础开始,逐步深入安卓开发的世界,通过实际案例和代码示例,展示如何构建自己的第一个安卓应用。我们将探讨基本概念、开发工具设置、用户界面设计、数据处理以及发布应用的全过程。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在安卓开发的道路上迈出坚实的步伐。
31 5
|
20天前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
|
21天前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
21天前
|
搜索推荐 前端开发 测试技术
打造个性化安卓应用:从设计到开发的全面指南
在这个数字时代,拥有一个定制的移动应用不仅是一种趋势,更是个人或企业品牌的重要延伸。本文将引导你通过一系列简单易懂的步骤,从构思你的应用理念开始,直至实现一个功能齐全的安卓应用。无论你是编程新手还是希望拓展技能的开发者,这篇文章都将为你提供必要的工具和知识,帮助你将创意转化为现实。
|
21天前
|
搜索推荐 Android开发 开发者
安卓应用开发中的自定义控件实践
在安卓应用开发的广阔天地中,自定义控件如同璀璨的星辰,点亮了用户界面设计的夜空。它们不仅丰富了交互体验,更赋予了应用独特的个性。本文将带你领略自定义控件的魅力,从基础概念到实际应用,一步步揭示其背后的原理与技术细节。我们将通过一个简单的例子——打造一个具有独特动画效果的按钮,来展现自定义控件的强大功能和灵活性。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇通往更高阶UI设计的大门。
|
21天前
|
Java Android开发 开发者
探索安卓开发:构建你的第一个“Hello World”应用
在安卓开发的浩瀚海洋中,每个新手都渴望扬帆起航。本文将作为你的指南针,引领你通过创建一个简单的“Hello World”应用,迈出安卓开发的第一步。我们将一起搭建开发环境、了解基本概念,并编写第一行代码。就像印度圣雄甘地所说:“你必须成为你希望在世界上看到的改变。”让我们一起开始这段旅程,成为我们想要见到的开发者吧!
27 0
|
24天前
|
存储 监控 Java
探索安卓开发:从基础到进阶的旅程
在这个数字时代,移动应用已成为我们日常生活的一部分。对于开发者来说,掌握安卓开发不仅是技能的提升,更是通往创新世界的钥匙。本文将带你了解安卓开发的核心概念,从搭建开发环境到实现复杂功能,逐步深入安卓开发的奥秘。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的见解和技巧,帮助你在安卓开发的道路上更进一步。
20 0