为了账号安全,请及时绑定邮箱和手机立即绑定
5.8 添加C/C++支持

本部分会学习如何在 Android Studio 中添加 C/C++ 支持,包括 NDK 及 CMake相关的知识。 Android 应用开发很多都是使用 Java 或 Kotlin 语言,但是对运行效率要求比较高或者对安全性要求比较高的模块,往往会采用 C/C++来编写。通过本部分的学习之后,我们就会了解如何在 Java 中调用 C/C++ 接口。

1. 概述

Android 分析工具位于以下位置:android_sdk/platform-tools/主要的命令行工具有如下这些:dumpsys一种在 Android 设备上运行的工具,可提供有关系统服务的信息。dmtracedump一种用于从跟踪日志文件生成图形化的调用堆栈图的工具。systrace借助该工具收集和检查设备上在系统一级运行的所有进程的时间信息。

5. 本教程适合哪些人群?

零基础的开发者(会从编程语言的最基础开始讲起);有一定 Java、C 或 C++ 开发基础开发者想学习 Kotlin 开发;Android 开发者想学习 Kotlin 开发 Android 应用;Java 后端开发者想学习 Kotlin 开发后端应用;对 Kotlin 语言感兴趣的所有开发者。

2.1 代码编辑器

Android Studio 的编辑器基于 IntelliJ IDEA 而来,可同时支持 Kotlin,Java和C / C ++ 语言,提供了基本补全、智能补全和语句补全功能,还支持创建自定义代码补全模板。Android Studio 提供了一个名为 Lint 的代码扫描工具,可帮助你发现并更正代码结构质量的问题,而无需执行应用或编写测试。每次编译你的应用时,Android Studio 都会运行 Lint 来检查你的源文件是否有潜在的错误,以及在正确性、安全性、性能、易用性、无障碍性和国际化方面是否需要优化改进。

1. SQLite 是什么

SQLite 是一个开源的轻量级关系数据库管理系统,简称RDMS(Relational Database Management System)。Android 通过 SQLIte 来进行数据库增删改查等相关操作,如果想进一步了解 SQLite,可以参考慕课网的数据库相关课程,这里主要围绕 Android 中的使用方法来展开。Android 已经预置了 SQLite DateBase,所以我们不需要做任何的依赖配置,跟前面几种存储方式一样,存储在 SQLite 的数据也是 App 的私有数据,也就是只有自己的 App 能够访问,这样能够保证数据安全。

3.3 验证命令选项

命令选项说明–print-certs显示有关 APK 签名证书的信息。–min-sdk-version用来确认 APK 签名将通过验证的最低 Android 框架 API 级别。–max-sdk-version用来确认 APK 签名将通过验证的最高 Android 框架 API 级别。–verbose使用详细输出模式。-Werr将警告视为错误。

Gradle Wrapper 详解

前面一小节《Android项目Gradle配置详解》中我们介绍了 Android 项目的目录及 Gradle 配置,我们提到有个目录是/gradle/wrapper。今天这篇文章我们来学习 Gradle Wrapper。通过这篇文章我们将了解什么是 Gradle Wrapper?为什么需要用 Gradle Wrapper?以及 Gradle Wrapper 的重要性。

3. 构建 app bundle

Android App Bundle 包含应用的所有经过编译的代码和资源,但 APK 的生成和签名将转到 Google Play 上来完成。与 APK 不同的是,我们不能直接将 app bundle 部署到设备上。如需构建 app bundle,最简单的方法是使用 Android Studio。不过,如果需要从命令行构建 app bundle,我们可以使用 Gradle 或 bundletool 来执行这项操作。

1. 概述

Android SDK 平台工具位于以下位置:android_sdk/platform-tools/主要的命令行工具有如下这些:adbAndroid 调试桥 (adb) 是一种多功能的工具,您可以用它来管理模拟器实例或 Android 设备的状态。还可以使用它在设备上安装 APK。logcat此工具可通过 adb 调用,用于查看应用和系统日志。fastboot将平台或其他系统映像刷写到设备上。

内容提供者 - Content Provider

本节学习最后一个 Android 组件——内容提供者。顾名思义,它可以用来给其他的 App 提供各种内容,比如 Android 自带的短信、联系人、日历等等都是一个普通的 App,当你需要这些内容的时候,就可以向它们的 Content Provider 发起请求,然后拿到相应的数据。

1.2 Json 的元素类型

Json 内部只有对象和数组两种类型,如下是一个 Json 对象的数据样例:{ "Engineer": { "skill": "Android", "language": "Java", "years": 5 } } 上面简短的 Json 数据对应一个“工程师”对象,里面包含技术、开发语言和工龄。再来看一个工程师对象数组:{"Engineers": [ { "skill": "Android", "language": "Java", "years": "5" }, { "skill": "iOS", "language": "Object C", "years": "2" }, { "skill": "Server", "language": "php", "years": "8" }]}以上 Json 数据就是一个包含 3 个“工程师”的对象数组。

广播接收器:Broadcast Receiver

今天带来 Android 第三大组件——Broadcast Receiver,可以用于和自己或者其他 App 发送消息,和 Service 一样,它也没有自己的 UI 界面。Broadcast Receiver 的设计模式非常类似发布/订阅模式,可用于做进程间通信(IPC)。通过本节的学习你可以详细的了解到 Android 中广播的作用和使用方法,并且能够将其灵活的运用到实际开发中。

2.2 如何修改自动更新版本

既然 Android Studio 有各种版本,在检查更新时如何选择要检查哪种发布版本呢?要修改检查更新的版本,可以按如下方法操作:依次点击 File > Settings(在 Mac 上,依次点击 Android Studio > Preferences)打开 Preferences 窗口;在左侧面板中,依次点击 Appearance & Behavior > System Settings > Updates;确保已选中 Automatically check for updates,然后从下拉列表中选择一个版本;点击 OK 完成。

3.2 在运行期判断

运行期判断是指代码已经编译到发行包里面,所以我们还是需要来判断当前是在哪个平台上面运行。这个时候可以使用 uni.getSystemInfoSync().platform 方法来判断当前的平台是Android,iOS还是小程序开发工具。在百度小程序开发工具、微信小程序开发工具、支付宝小程序开发工具中使用 uni.getSystemInfoSync().platform 返回值都是 devtools,所以我们只能知道当前是小程序开发工具,不能继续往下细分了。实例:switch(uni.getSystemInfoSync().platform){ case 'android': console.log('运行在Android平台上面') break; case 'ios': console.log('运行在iOS平台上面') break; default: console.log('运行在开发者工具上面') break;}

Android Studio 如何关联 Gradle

前面的小节我们学习了如何配置 CMake。本小节学习如何把原生库和 Gradle 构建关联起来。

1. 什么是签名

现在你写了一本书并签上自己的大名,将它出版之后放到各大书店,理想状态就是读者通过书名就能找到它。但是市面上的书不计其数,难免会有书名雷同,亦或是你的书大卖,市面上出现了盗版、翻版,这时候光靠书名已经没办法辨别,你的签名就能发挥作用了。今后如果你要出续集,同样,为了避免读者买到的是续集而不是同名的其他书,也需要在找到书名之后再次确认一下你的签名,两者一致才能认定这就是续集。这一章提到的签名和现实中的签名非常类似,只不过在这里我们称为“数字签名”。在 Android 系统中,所有安装到系统的App都必有一个数字证书,此数字证书用于标识应用程序的作者和应用程序之间的信任关系。Android 使用 Java 的数字证书相关的机制来给 apk 加盖数字证书,数字证书的私钥由开发者持有。Android 使用证书作为标识应用程序作者的一种方式,和 Https 不同,Android 证书不需要由证书认证中心签名,开发者直接使用自制签名证书。所以我们在打包 apk 的时候,必须对 apk 用自己的证书做一次签名打包,用于在市场上唯一标识发布者的身份。一般 Android 有两种签名:调试模式的签名: Android sdk 为应用自动生成一个签名证书,调试模式下签名的应用不能对外发布,因为由构建工具创建的证书是不安全的,应用商店不接受调试证书签名的 apk;公布模式下签名: 需要生成自己的证书,可用于发布。

3. 编写垂直样式布局

线性布局分为垂直和水平布局两种方式,在使用过程中除了方向不同,其余类似。本节仅演示垂直样式,水平样式相信你能够触类旁通。顾名思义,垂直布局就是将内部 View 从上到下依次排成一列,为了便于理解,直接上代码,在我们新建的工程中,找到“res->layout->activity_main.xml”,编写代码如下:<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30sp" android:text="Here" android:background="#E71B0C"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30sp" android:text="Is" android:background="#E7430F"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30sp" android:text="Imooc" android:background="#E6D11B"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30sp" android:background="#88F10D" android:text="Android"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="30sp" android:background="#03A9F4" android:text="Study"/></LinearLayout>直接编译,效果如下:如图,在屏幕中有 5 个 TextView 按照垂直方向依次排成一列。注意,Layout 都是继承自 ViewGroup 的,在上一节我们说过 ViewGroup 也是 View,所以我们可以推理出 Layout 里面也是可以放 Layout 的。按照这个逻辑我们还可以在垂直布局中嵌套水平布局,比如我们希望把“Here Is”和“Android Study”这两个短语写到一排:<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#E71B0C" android:text="Here" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#E7430F" android:text="Is" android:textSize="30sp" /> </LinearLayout> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#E6D11B" android:text="Imooc" android:textSize="30sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#88F10D" android:text="Android" android:textSize="30sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#03A9F4" android:text="Study" android:textSize="30sp" /> </LinearLayout></LinearLayout>直接运行:我们将“Here”和“Is”、“Android”和“Study”这四个 TextView 两两一组分别放到了一个水平样式的 LinearLayout 中,这样验证了,Layout 是可以嵌套使用的。

1. 概述

Android 模拟器工具位于以下位置:android_sdk/emulator/主要的命令行工具有如下这些:emulator一种基于 QEMU 的设备模拟工具,可用于在实际的 Android 运行时环境中调试和测试应用。mksdcard可帮助我们创建可与模拟器一起使用的磁盘映像,以模拟存在外部存储卡(例如 SD 卡)的情形。

2.2 创建模拟器

打开模拟器管理器,依次点击 Tools > AVD Manager;在模拟器管理器内点击 Create Virtual Device;选择模拟器硬件配置,默认即可,点击 Next;选择模拟器 Android 系统类型,点击 Download 可以在线下载,点击 Next;确认模拟器配置,默认即可,点击 Finish;Android Studio 中即可看到我们刚创建的模拟器了。

1. AndroidStudio 项目结构

我们介绍 AndroidStudio 中 Android 项目的 Gradle 配置之前,我们先来看下 AndroidStudio 中 Android 项目的结构,我们新建一个项目结构大致如下图所示:我们通过上面的图片可以看到,Android 项目中跟 Gradle 相关的主要有 7 个部分:根目录下的 build.gradle: 顶级构建文件,配置 Gradle 版本和 Maven 依赖;app 目录下的 build.gralde文件: app 打包和签名配置,及模块的依赖;gradle 文件夹: 配置 gradel-wrapper;setting.gradle 文件: 添加编译的所有模块;gradle.projects 文件: 项目范围的梯度设置,编译内存,Gradle 并发性等设置。;gradlew 和 gradlew.bat 文件: Gradle 启动脚本文件;.gradle 文件夹: 编译时的缓存文件夹。这几个部分各自负责的功能都不尽相同。下面我们来看下它们具体的功能。

活动:Activity

从今天开始将会学习一个非常重要的概念——Android 四大组件,在 Android 中几乎所有的功能都和四大组件密不可分,而 Activity 是其中出场率最高的组件,也是对用户感知度最高的组件,当然也可以说是四大组件中最重要的一个组件。我们前面的绝大部分逻辑代码也都是在 Activity 中实现的,接下来详细介绍一下第一大组件——Activity。

1. 多语言支持

Android 应用可以包含特定于文化的字符串,这些字符串将转换为当前语言区域的语言。Android 会根据系统语言区域设置来解析特定于语言和文化的资源。我们可以使用 Android 项目中的资源目录为不同的语言区域提供支持,我们可以提供适合用户的语言和文化的任何资源类型。例如,以下图片显示了一个应用,它按设备的默认 (en_US) 语言区域和西班牙语 (es_ES) 语言区域显示字符串和可绘制资源。要添加对更多语言区域的支持,我们需要在 res/ 内创建额外的目录。每个目录的名称都应遵循以下格式:<resource type>-b+<language code>[+<country code>]例如,values-es-rUS/ 包含适用于语言代码为 es 的语言区域的字符串资源,Android 在运行时根据设备的语言区域设置加载适当的资源。例如:FirstApp/ res/ values/ strings.xml values-es-rUS/ strings.xml英语字符串(默认语言区域),/values/strings.xml:<resources> <string name="hello_world">Hello World!</string></resources>西班牙语字符串(语言区域为 es),/values-es-rUS/strings.xml:<resources> <string name="hello_world">¡Hola Mundo!</string></resources>

3.1 布局文件

首先我们来通过 xml 编写布局文件,根据上面的需求要在 ViewFlipper 中放入 3 个布局。我们用一个 RelativeLayout 作为一个 ViewFlipper 的子 View 占满一屏内容,只需要包含三个这样的 RelativeLayout 即可,代码如下:<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:showIn="@layout/activity_main"> <ViewFlipper android:id="@+id/view_flipper" android:layout_width="fill_parent" android:layout_height="fill_parent" android:inAnimation="@anim/in_from_right" android:outAnimation="@anim/out_from_left"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center" android:adjustViewBounds="true" android:background="@android:color/black" android:scaleType="centerCrop" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:gravity="center" android:text="第一屏:好好学Android" android:textColor="@android:color/white" android:textSize="18dp" android:textStyle="bold" /> </RelativeLayout> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center" android:adjustViewBounds="true" android:background="@android:color/darker_gray" android:scaleType="centerCrop" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:gravity="center" android:text="第二屏:在慕课网好好学Android" android:textSize="18dp" android:textStyle="bold" /> </RelativeLayout> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center" android:adjustViewBounds="true" android:background="@android:color/holo_green_light" android:scaleType="centerCrop" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:gravity="center" android:text="第三屏:在慕课网跟着超哥好好学Android" android:textSize="18dp" android:textStyle="bold" /> </RelativeLayout> </ViewFlipper></RelativeLayout>可以看到其实 ViewFlipper 的子 View 和我们平时开发时用到的布局没有什么差别,然后将每一屏的内容作为 ViewFlipper 的子 View 添加进去即可。

2. dumpsys

dumpsys 是一种在 Android 设备上运行的工具,可提供有关系统服务的信息。我们可以使用 Android 调试桥 (ADB) 从命令行调用 dumpsys,获取在连接的设备上运行的所有系统服务的诊断输出。此输出通常比我们想要的更详细,因此我们可以使用下文所述的命令行选项仅获取我们感兴趣的系统服务的输出。

3.2 编写入场和出场动画

细心的朋友们应该会注意到,在布局文件的<ViewFlipper/>标签中有这么两个属性:android:inAnimation="@anim/in_from_right"android:outAnimation="@anim/out_from_left"根据 2.1 小节对属性的介绍,我们知道这是用来设置出场和入场动画的,所以接下来我们就来完善这两个动画效果,首先按照以下步骤创建一个动画资源:右键点击“res”目录,一次选择“New” -> “Android Resource Directory”在“Resource type”中选择“anim”,点“OK”,创建一个动画资源目录此时“res”目录下就有了“anim”文件夹,在里面创建四个动画文件:in_from_left.xml:表示从左侧进入的动画,代码如下:<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <translate android:duration="1400" android:fromXDelta="-100%" android:toXDelta="0%"/></set>其中<translate/>标签表示一个 TranslateAnimation,专门用来实现移动补间动画,具体关于动画的用法在后面的动画专题章节有详细的讲解,这里我们关注 ViewFlipper,对动画只需要做一点了解即可。其余三个动画都类似:**in_from_right.xml:**表示从右侧进入,代码如下:<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <translate android:duration="1400" android:fromXDelta="100%" android:fromYDelta="0%" /></set>**out_from_left:**从左侧移出:<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <translate android:duration="1400" android:fromXDelta="0%" android:toXDelta="-100%"/></set>**out_from_right:**从右侧移出:<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <translate android:duration="1400" android:fromXDelta="0%" android:fromYDelta="0%" android:toXDelta="100%" android:toYDelta="0%" /></set>

2.2 指定 API 级别要求

如果我们的应用需要特定的最低 Android 平台版本,我们可以在应用的 build.gradle 文件中将该版本要求指定为 API 级别设置。在构建流程中,这些设置将合并到应用的清单文件中。指定 API 级别要求可确保只能将我们的应用安装在运行兼容的 Android 平台版本的设备上。有两种 API 级别设置:minSdkVersion:可运行应用的最低 Android 平台版本,由平台的 API 级别标识符指定。targetSdkVersion:指定运行应用的目标 API 级别。在某些情况下,这允许应用使用针对目标 API 级别定义的清单元素或行为,而不是仅限于使用那些针对最低 API 级别定义的清单元素或行为。示例如下:android { ... defaultConfig { ... minSdkVersion 14 targetSdkVersion 24 }}在准备安装我们的应用时,系统会检查这些设置的值,并将其与系统版本进行比较。如果 minSdkVersion 值大于系统版本,系统会阻止安装应用。

3.1 创建默认布局文件

我们可以通过以下方式之一创建新布局:使用 Android Studio 的主菜单在 Project 窗口中,点击要在其中添加布局的模块;在主菜单中,依次选择 File > New > XML > Layout XML File;在显示的对话框中,提供文件名、根布局标记以及布局所属的源代码集;点击 Finish 以创建布局。使用 Project 视图从 Project 窗口中选择 Project 视图;右键点击想要在其中添加布局的布局目录;在显示的上下文菜单中,依次点击 New > Layout Resource File。使用 Android 视图从 Project 窗口中选择 Android 视图;右键点击 layout 文件夹;在显示的上下文菜单中,依次选择 New > Layout Resource File。

4.1 选择项目类型

在向导的 Choose your project 屏幕顶部,显示了各种设备类型对应的项目类别选项卡,你可以从中选择要创建的项目类型。Tips:上图的选择会为所选的手机和平板电脑创建基本的 Android Activity。在你选择要创建的项目类型后,Android Studio 会填充示例代码和资源,以帮助你开始创建项目。选择后,点击 Next。

6. 小结

本节学习了一个比较专业的存储方式,SQLite 是一种轻量级的开源数据库框架,已经被预置到 Android 系统中,我们可以非常方便的使用。既可以通过标准的 SQL 语句进行操作,也可以使用 Android 提供的 Java 接口做 CURD。通过最后一个例子可以学习到 SQLite 的所有常用接口,在今后需要用到数据库的时候,可以回头来看看本节的例子。

3.3 更改资源目录

默认情况下,我们的资源位于 module-name/src/source-set-name/res/。例如,模块的主源代码集的资源位于 src/main/res/,调试源代码集的资源则位于 src/debug/res/。不过,我们可以使用 sourceSets {} 块中的 res.srcDirs 属性将这些路径更改为任何其他位置(相对于 build.gradle 文件)。例如:android { sourceSets { main { res.srcDirs = ['resources/main'] } debug { res.srcDirs = ['resources/debug'] } }}我们还可以为一个源代码集指定多个资源目录,构建工具会将它们合并在一起。例如:android { sourceSets { main { res.srcDirs = ['res1', 'res2'] } }}

直播
查看课程详情
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号