为了账号安全,请及时绑定邮箱和手机立即绑定
3. 小结

本节课程我们主要学习了 Android 模拟器的安装、创建和管理。本节课程的重点是:能够按照自己的要求完成虚拟设备的创建。

2. 多线程注意事项

Android 规定刷新 UI 的操作必须在主线程执行;网络请求、数据库或者文件 I / O 等都属于耗时操作,非常容易导致主线程的阻塞造成 App 卡顿;由于主线程的 Looper 是按顺序轮询 MessageQueue 的,所以主线程的所有任务都是同步执行。这样如果有耗时操作那么会阻塞主线程,后面的任务都需要等待耗时操作的执行;除了 I / O 操作外,开发人员需要自行评估任务的耗时情况,合理采用多线程避免主线程的阻塞;Android 提供了多种创建和管理线程的方法,当然如果有高并发的场景还有一些第三方库可以使用,但是系统的线程、线程池可以应对大部分常见场景。接下来我们来看看具体怎么使用 Android 多线程。

3. 如何签名打包

签名打包的方式有很多,这里介绍一种最简单的方式,直接使用Eclipse就可以为我们的 App 签名打包。在 Eclipse 中选择“File” -> “Export”,选择“Android” -> “Export Android Application”;这时候提示我们创建一个密钥库 keystore,选择 Create new keystore,然后指定一个保存证书的目录并设置证书密码;接着填写密钥库信息,填写证书文件的密码,使用期限和组织单位的信息,这样一个证书就生成好了。回到第一步,在 Export 的时候选择“Use existing keystore”,然后选择刚刚创建的证书,并输入密码,一路 next,搞定!再看看 Eclipse 的 bin 目录,就会出现刚刚我们用自己的证书签名的 apk,待我们后面学习 Android 功能开发之后,你就可以用这种方式签名打包自己的 apk 进行发布了。

吐司提示:Toast 的使用方法

在使用 Android 手机的时候,有没有遇到过如图中这种类型的消息提示?这个在 Android 中被称为 Toast,用来短暂的展示一些简短的提示信息。相比弹窗来讲它对用户的打扰更小,在提示一段时间之后会自动消失,通常用来提示当前的状态或者一些不太重要的信息。接下来我们先看看 Toast 的相关特性然后一起动手编写一些与 Toasts 相关的示例代码。

1. 开发应用的基本流程

日常开发一款 Android 应用的基本流程包括创建项目、编写应用、构建并运行、调试分析及测试、发布。

2. AndroidStudio 的安装

AndroidStudio 的安装非常简单,只需要简单点击下一步即可。这里推荐安装最新版本的 AndroidStudio 。Tips:Android Studio 的安装可以参考慕课 Wiki 《Android Studio 编辑器教程》。

2.1 使用 Intent 打开

通过使用 MediaStore 类提供的两个 Intnet 常量,可以直接将相机操作托管给 Android 系统而无需创建 Camera 实例:ACTION_IMAGE_CAPTURE:拍摄照片ACTION_VIDEO_CAPTURE:拍摄视频

2.2 编写 Kotlin 业务代码,运行 App

实际上只需上面简单创建 Kotlin 相关依赖就自动配置完成了,现在只需简单运行就可以把这个 Android 应用程序跑起来:

3. 配置特定版本的 NDK

如果我们安装特定版本的 NDK 并希望在模块中使用它,请使用模块的 build.gradle 文件中的 android.ndkVersion 属性进行指定,如以下代码示例所示。android { ndkVersion "major.minor.build"}

3.1 如何查看内存分配

内存分配为我们显示内存中的每个 Java 对象和 JNI 引用是如何分配的。具体而言,Memory Profiler 可为我们显示有关对象分配的以下信息:分配了哪些类型的对象以及它们使用多少空间;每个分配的堆栈轨迹,包括在哪个线程中;对象在何时被取消分配。如果我们的设备搭载的是 Android 8.0 或更高版本,我们可以随时查看对象分配,具体操作步骤如下:在时间轴上拖动以选择要查看哪个区域的分配。不需要开始记录会话,因为 Android 8.0 及更高版本附带设备内置分析工具,可持续跟踪我们的应用分配。11如果我们的设备搭载的是 Android 7.1 或更低版本,请点击 Memory Profiler 工具栏中的 Record memory allocations 图标。记录时,Memory Profiler 会跟踪我们的应用中发生的所有分配。完成后,请点击 Stop recording 图标以查看分配。12

Resource Manager 工具

前一小节我们介绍了 Android 的应用资源相关的知识,本小结我们学习如何使用 Resource Manager 管理应用的界面资源。

触摸事件分发

用户在使用 Andriod 系统的时候会不断的和我们的 App 进行各种类型的交互(类似点击、滑动等等),“事件”就是一个非常有效的用来收集用户行为的方式。在前面章节有提到过:Android 系统采用一个先进先出(FIFO)队列来维护一个事件 List。在每个事件出列的时候,Android 系统会根据一定的规则对这些事件做分发,我们可以通过接收这些事件来对用户的操作进行相应的处理。

HTTP 使用详解

在你浏览互联网的时候,绝大多数的数据都是通过 HTTP 协议获取到的,也就是说如果你想要实现一个能上网的 App,那么就一定会和 HTTP 打上交道。当然 Android 发展到现在这么多年,已经有很多非常好用,功能非常完善的网络框架了,比如 Volley、OkHttp、retrofit等,但是底层逻辑都是一样的。本节我们来学习 Android 原声支持的 HTTP 接口,相比那些第三方框架,它的封装更好,也更适合我们了解底层原理。

4.1 编写布局文件

布局文件非常简单,核心就是一个 ImageView,用来承载我们缩放的目标图片。需要注意的是,这里要将图片的 scaleType设置成“matrix”,用于后续做缩放:<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" android:padding="20dp" tools:context=".MainActivity"> <TextView android:id="@+id/textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:text="手势处理示例" android:textSize="35sp" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/textview" android:layout_centerHorizontal="true" android:text="慕课 Android 教程" android:textColor="#ff7aff24" android:textSize="35dp" /> <ImageView android:id="@+id/imageView" android:layout_width="40dp" android:layout_height="40dp" android:layout_below="@+id/textView" android:layout_alignParentStart="true" android:layout_alignParentEnd="true" android:layout_alignParentBottom="true" android:scaleType="matrix" android:src="@drawable/avatar" /></RelativeLayout>

2.2 通过 Gradle 配置

通过 Android Plugin for Gradle,我们可以使用模块级 build.gradle 文件中的 lintOptions {} 代码块配置某些 lint 选项,例如要运行或忽略哪些检查。以下代码段展示了可以配置的部分属性:android { ... lintOptions { // Turns off checks for the issue IDs you specify. disable 'TypographyFractions','TypographyQuotes' // Turns on checks for the issue IDs you specify. These checks are in // addition to the default lint checks. enable 'RtlHardcoded','RtlCompat', 'RtlEnabled' // To enable checks for only a subset of issue IDs and ignore all others, // list the issue IDs with the 'check' property instead. This property overrides // any issue IDs you enable or disable using the properties above. check 'NewApi', 'InlinedApi' // If set to true, turns off analysis progress reporting by lint. quiet true // if set to true (default), stops the build if errors are found. abortOnError false // if true, only report errors. ignoreWarnings true }}...

2.1 General 标签

在 General 标签中,我们可以指定安装、启动和部署选项。Module选择要应用此配置的模块。Installation Options:DeployDefault APK:为我们当前选择的变体构建和部署 APK。APK from app bundle:从 Android App Bundle 构建和部署应用。也就是说,Android Studio 会先将我们的应用项目转换为 app bundle,其中包含了应用的所有经过编译的代码和资源。然后,Android Studio 仅会从该 app bundle 生成将应用部署到已连接的设备所需的 APK。通常,在测试想要上传到 Google Play 的 app bundle 时应使用此选项,因为从 app bundle 部署应用会延长总构建时间。Custom Artifact:在 Android Studio 中不受支持。Nothing:不在设备上安装 APK。例如,如果我们更愿意手动安装 APK,则无需使用 Android Studio 进行安装。Installation Options:Deploy as instant app如果我们的应用支持免安装体验(也就是说,我们在创建新项目时添加了对免安装应用的支持,或者我们创建了一项或多项支持免安装体验的动态功能),则我们可以选择部署这些支持免安装体验的模块,方法是勾选 Deploy as instant app 旁边的复选框。Installation Options:Dynamic features to deploy如果我们的应用包含动态功能模块,在部署应用时,请选中要包含的每个动态功能旁边的复选框。只有在应用包含动态功能时,才会看到此选项。Installation Options:Install Flags键入我们要使用的任何 adb pm install 选项。设置选项格式的方式与在命令行上相同,但不指定路径。Launch Options:LaunchNothing:当我们选择 Run 或 Debug 时,不启动任何内容。不过,如果我们的应用已在运行且我们选择了 Debug ,则 Android Studio 会将调试程序连接到我们的应用进程。Default Activity:启动在清单中标记为启动项的 Activity。Specified Activity:启动模块中特定的应用 Activity。选择此选项后,Activity 字段将显示在下方,我们可以在其中输入要启动的 Activity 的名称,也可以点击 More 以从列表中选择一个 Activity。URL:启动与应用清单中的 intent 过滤条件匹配的网址。选择此选项后,URL 字段将显示在下方,我们可以在其中输入网址。Launch Options:Launch Flags键入我们要使用的任何 adb am start 选项。设置选项格式的方式与在命令行上相同,但不指定 intent。Before Launch定义启动之前的操作。

1. 菜单的几种类型

根据不同的业务场景和不同的样式,Android 提供了以下 3 种菜单:Option Menu: 选项菜单Context Menu: 上下文菜单Pop-up Menu: 弹窗菜单下面来分别介绍这 3 种菜单类型

3. Json 解析示例

本节我们来用 Android 原生的 Json 工具对 1.2 小节中的“工程师”数据进行一个解析,主需要用到必考的两个类:JSONArray和JSONObject。

Android Studio 的运行配置

前面的小节我们介绍了代码编辑和资源管理方面的知识,从本小结开始我们学习编译运行相关的知识,首先我们学习下编译运行前的配置。

Android Studio 的 Translations Editor工具

前一小节我们介绍了如何使用 Resource Manager 管理界面资源,本小结我们学习如何使用 Translations Editor 处理字符串多语言翻译。

3.2 为应用签名

要使用 Android Studio 为我们的应用签名,并导出现有的应用签名密钥,请按以下步骤操作:在菜单栏中依次点击 Build > Build > Generate Signed Bundle/APK;在 Generate Signed Bundle or APK 对话框中,选择 Android App Bundle 或 APK,然后点击 Next;指定密钥库的路径、密钥的别名,然后输入二者的密码,然后点击 Next;为签名的应用选择一个目标文件夹、选择构建类型,选择签名版本,然后点击 Finish。至此,我们的应用就编译并且签名完成,可以上传至应用市场或自己的服务器。

3. 添加 NDK API

Android NDK 提供了一套我们可能会觉得非常实用的原生 API 和库。通过在项目的 CMakeLists.txt 脚本文件中包含 NDK 库,我们可以使用其中任何 API。Android 平台上已存在预构建的 NDK 库,因此我们无需构建它们或将它们打包到 APK 中。由于这些 NDK 库已位于 CMake 搜索路径中,因此我们甚至无需指定本地安装的 NDK 库的位置,我们只需为 CMake 提供我们想要使用的库的名称,并将其与我们自己的原生库相关联即可。向 CMake 构建脚本添加 find_library() 命令以找到 NDK 库并将其路径存储为一个变量。我们可以使用此变量在构建脚本的其他部分引用 NDK 库。以下示例可以找到 Android 专有的日志支持库,并会将其路径存储在 log-lib 中:find_library( # Defines the name of the path variable that stores the # location of the NDK library. log-lib # Specifies the name of the NDK library that # CMake needs to locate. log )为了让我们的原生库能够调用 log 库中的函数,我们需要使用 CMake 构建脚本中的 target_link_libraries() 命令来关联这些库:find_library(...)# Links your native library against one or more other native libraries.target_link_libraries( # Specifies the target library. native-lib # Links the log library to the target library. ${log-lib} )NDK 还以源代码的形式包含一些库,我们将需要构建这些代码并将其关联到我们的原生库。我们可以使用 CMake 构建脚本中的 add_library() 命令将源代码编译到原生库中。如需提供本地 NDK 库的路径,我们可以使用 Android Studio 自动为我们定义的 ANDROID_NDK 路径变量。例如,以下命令告诉 CMake 要构建 android_native_app_glue.c(负责管理 NativeActivity 生命周期事件和触摸输入),并将其链接到静态库 native-lib 中:add_library( app-glue STATIC ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )# You need to link static libraries against your shared native library.target_link_libraries( native-lib app-glue ${log-lib} )

2.3 点击事件监听器

ListView 的样式示意图如下:ListView 中的每个 item 可以设置成任意样式,可以包含任意的 Android 控件,非常灵活。接下来,我们来一起看看如何使用。

1. SharedPreferences 特点

在 Android 中,Shared Preferences 专门用于存储一些基本数据类型(integer, float, boolean, string, long),它通过一种Key-Value的数据结构存储在私有目录中。我们可以通过 Shared Preferences 的接口获取一个指向 Key-Value 文件的对象,相比操作文件可以更轻松的通过 Shared Preferences 进行数据的读取和写入。该接口由 Android 系统负责管理,我们可以在任何地方通过接口操作 Shared Preferences,而且只有自己的 App 能够访问,是比较安全的存储方式,非常适合存储一些轻量级的数据,类似“记住密码”、“自动登录”、“各种设置”的场景。

5 小结

本节学习的是 Android 第三个组件,Android 预置了很多个系统广播,主要用于让 App 很方便的接收一些系统事件。广播分为有序广播和无序广播,有序广播会按照优先级顺序依次发送给 Receiver,而无序广播则是同时发送,相比之下无序广播的效率更高,但是不可控。如果希望自定义广播,可以直接创建一个 BroadcastReceiver 的子类,覆写onReceive(),这样就可以从 intent 中取到数据了。使用广播,可以很方便的在应用内、应用间传递消息,对功能解耦、事件传递等场景非常适用,你学会了吗?

3. 获取 Bitamp 实例

Android 提供了多种方法获取 Bitamp 实例,我们可以直接从 ImageView 上拿到当前设置的图片的 Bitamp 对象:private Bitmap bmp;private ImageView img;img = (ImageView)findViewById(R.id.imageView);BitmapDrawable drawable = (BitmapDrawable)img.getDrawable();bmp = drawable.getBitmap();从上面的代码中也可以看到我们可以通过 Drawable 的getBitmap()方法从 Drawable 对象中提取出 Bitamp。Android 还提供了一个 BitampFractory 工厂对象,专门让我们去获取 Bitmap 实例,主要有以下几种常用方法:// 从资源文件中解码出 Bitmapprivate Bitmap getBitmapFromResource(Resources res, int resId) { return BitmapFactory.decodeResource(res, resId);}// 从图片文件中获取private Bitmap getBitmapFromFile(String pathName) { return BitmapFactory.decodeFile(pathName);}// 从像素数组中获取public Bitmap Bytes2Bimap(byte[] b) { if (b.length != 0) { return BitmapFactory.decodeByteArray(b, 0, b.length); } else { return null; }}// 读取输入流private Bitmap getBitmapFromStream(InputStream inputStream) { return BitmapFactory.decodeStream(inputStream);}

1. 内容提供者的定义

照旧,首先看看官方解释:Content providers are one of the primary building blocks of Android applications, providing content to applications. They encapsulate data and provide it to applications through the single ContentResolver interface. A content provider is only required if you need to share data between multiple applications. For example, the contacts data is used by multiple applications and must be stored in a content provider. If you don’t need to share data amongst multiple applications you can use a database directly via android.database.sqlite.SQLiteDatabase.When a request is made via a ContentResolver the system inspects the authority of the given URI and passes the request to the content provider registered with the authority. The content provider can interpret the rest of the URI however it wants. The UriMatcher class is helpful for parsing URIs.文档解释略长,这里用自己的话简要描述一发:Content Provider 是 Android 四大组件之一,通过它可以向其他 App 提供数据。当收到其他 App 的数据请求时,会有一个 Content Resolver 接口统一对请求进行处理。数据请求通过 URI 的形式发起,每一次请求都需要带上 URI,Content Resolver 非常灵活并且可控性很强,在这里我们可以对来访者做鉴权,然后根据权限的不同给予不同敏感级别的数据,甚至可以对部分 App 拒绝提供数据。Content Provider 对数据的管理方式并不关心,可以采用 DataBase、文件、远程服务端等等 Android 支持的任何一种形式,整个工作流程如下:

3. 小结

本节课程我们主要学习了 Android Studio 如何创建一个应用实例。本节课程的重点如下:开发应用的基本流程如何快速创建一个应用

4. Genymotion 的创建与运行

打开 Genymotion,此时会自动启动 VirtualBox。选择“personalUse”,用上一步注册的账号登录。接着点击“Add”添加一个 Android 设备,按照自己的需求选择相应的版本和尺寸。随后设置设备配置,点“Next”进入设备的下载。待该虚拟设备下载完成之后,你就会在主界面 Your virtual devices 列表中看到已经下载完成的虚拟设备了。最后双击或者点 start 即可启动添加的虚拟机,随后便可看到我们熟悉的 Android 界面了。你可以尝试拖拽文件、APK 到虚拟机窗口,或者任意改动窗口大小,体验一下 Genymotion 和上一章中 AVD 的差别吧。

3.1 编写 Activity 的布局文件

和前几节的例子一样,我们仅需要在根布局中防止一个 ExpandableListView 即可,然后设置上相应的属性,如下:<ExpandableListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/expandableListView" android:layout_width="match_parent" android:layout_height="match_parent" android:divider="@android:color/darker_gray" android:dividerHeight="0.5dp" android:indicatorLeft="?android:attr/expandableListPreferredItemIndicatorLeft" android:padding="30dp" />

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

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

帮助反馈 APP下载

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

公众号

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