Android高级技巧
高级技巧全局获取Context的技巧回想这么久以来我们所学的内容,你会发现有很多地方都需要用到Context,弹出Toast的时候 需要,启动Activity的时候需要,发送广播的时候需要,操作数据库的时候需要,使用通知的时 候需要……
或许目前你还没有为得不到Context而发愁过,因为我们很多的操作是在Activity中进行的, 而Activity本身就是一个Context对象。但是,当应用程序的架构逐渐开始复杂起来的时候, 很多逻辑代码将脱离Activity类,但此时你又恰恰需要使用Context,也许这个时候你就会 感到有些伤脑筋了。
例如,在第12章的Kotlin课堂中,我们编写了一个Toast.kt文件,并在这里对Toast的用法进行 了封装,代码如下所示:
fun String.showToast(context: Context, duration: Int = Toast.LENGTH_SHORT){ Toast.makeText(context, this, duration).show()}fun Int.showToast(contex ...
Jetpack
Jetpack简介Jetpack的家族还是非常庞大的,主要由基础、架构、行为、界面这4个部分组成。
ViewModelViewModel的一个重要作用就是可以帮助Activity分担一部分工作,它是专门用于存放与界 面相关的数据的。也就是说,只要是界面上能看得到的数据,它的相关变量都应该存放在 ViewModel中,而不是Activity中,这样可以在一定程度上减少Activity中的逻辑。
另外,ViewModel还有一个非常重要的特性。我们都知道,当手机发生横竖屏旋转的时候, Activity会被重新创建,同时存放在Activity中的数据也会丢失。而ViewModel的生命周期和 Activity不同,它可以保证在手机屏幕发生旋转的时候不会被重新创建,只有当Activity退出的 时候才会跟着Activity一起销毁。因此,将与界面相关的变量存放在ViewModel当中,这样即 使旋转手机屏幕,界面上显示的数据也不会丢失。ViewModel的生命周期如图13.2所示。
接下来就让我们通过一个简单的计数器示例来学习ViewModel的基本用法。
ViewModel的基本用法由于J ...
Mterial Design
Material Design什么是Material DesingMaterial Design是由Google的设计工程师们基于传统优秀的设计原则,结合丰富的创意和科 学技术所开发的一套全新的界面设计语言,包含了视觉、运动、互动效果等特性。
ToolbarActionBar,每个Activity最顶部的那个标题栏其实就是ActionBar。不过ActionBar由于其设计的原因,被限定只能位于Activity的顶部,从而不能实现一些 Material Design的效果,因此官方现在已经不再建议使用ActionBar了
Toolbar的强大之处在于,它不仅继承了ActionBar的所有功能,而且灵活性很高,可以配合其 他控件完成一些Material Design的效果,下面我们就来具体学习一下。
首先你要知道,任何一个新建的项目,默认都是会显示ActionBar的,这个想必你已经见识过太 多次了。那么这个ActionBar到底是从哪里来的呢?其实这是根据项目中指定的主题来显示的。 打开AndroidManifest.xml文件看一下,如下所示:
<application ...
协程
协程协程的基本用法Kotlin并没有将协程纳入标准库的API当中,而是以依赖库的形式提供的。所以如果我们想要使 用协程功能,需要先在app/build.gradle文件当中添加如下依赖库:
dependencies { ... implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1" ) implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1") }
第二个依赖库是在Android项目中才会用到的,本节我们编写的代码示例都是纯Kotlin程序,所 以其实用不到第二个依赖库。但为了下次在Android项目中使用协程时不再单独进行说明,这里就一同引入进来了。
接下来创建一个CoroutinesTest.kt文件,并定义一个main()函数,然后开始我们的协程之旅 吧。
首先我们要面临的第一个问题就是,如何开启一个协程?最简 ...
Android网络
网络WebView的用法借助它我们就可以 在自己的应用程序里嵌入一个浏览器,从而非常轻松地展示各种各样的网页。
新建一个 WebViewTest项目,然后修改activity_main.xml中的代码,如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width = "match_parent" android:layout_height = "match_parent"> <WebView android:id="@id/webView" android:layout_width = "match_parent" android:layout_height = "match_parent&quo ...
探究Service
ServiceService是什么Service是Android中实现程序后台运行的解决方案,它非常适合执行那些不需要和用户交互而 且还要求长期运行的任务。Service的运行不依赖于任何用户界面,即使程序被切换到后台,或 者用户打开了另外一个应用程序,Service仍然能够保持正常运行。
不过需要注意的是,Service并不是运行在一个独立的进程当中的,而是依赖于创建Service时 所在的应用程序进程。当某个应用程序进程被杀掉时,所有依赖于该进程的Service也会停止运行。
另外,也不要被Service的后台概念所迷惑,实际上Service并不会自动开启线程,所有的代码都是默认运行在主线程当中的。也就是说,我们需要在Service的内部手动创建子线程,并在这里执行具体的任务,否则就有可能出现主线程被阻塞的情况。
Android多线程编程当我们需要执行一些耗时操作,比如发 起一条网络请求时,考虑到网速等其他原因,服务器未必能够立刻响应我们的请求,如果不将 这类操作放在子线程里运行,就会导致主线程被阻塞,从而影响用户对软件的正常使用。
线程的基本用法义一 个线程只需要新建一个类继承自 ...
运用手机多媒体
运用手机多媒体将程序运行到手机上进入“关于手机”界面,然 后对着最下面的版本号那一栏连续点击,就会让开发者选项显示出来。然后进入设置→系统→ 开发者选项界面,并在这个界面中选中USB调试选项。
使用通知创建通知渠道通知渠道:每条通知都要属于一个对应的渠道
创建通知渠道的详细步骤首先需要一个NotificationManager对通知进行管理,可以通过调用Context的getSystemService()方法获取。getSystemService()方法接收一个字符串参数用于确定获取系统的哪个服务,传入Context.NOTIFICATION_SERVICE即可。
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
接下来要使用NotificationChannel类构建一个通知渠道,并调用NotificationManager的createNotificationChannel()方法完成创建。由于NotificationChannel类和createNotifica ...
探究ContentProvider
ContentProvider简介ContentProvider主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的 机制,允许一个程序访问另一个程序中的数据,同时还能保证被访问数据的安全性。目前,使 用ContentProvider是Android实现跨程序共享数据的标准方式。
运行时权限Android权限机制详解首先回顾一下过去Android的权限机制。我们在第6章写BroadcastTest项目的时候第一次接触 了Android权限相关的内容,当时为了要监听开机广播,我们在AndroidManifest.xml文件中 添加了这样一句权限声明:
<manifest xmlns:android="http://shemas.android.com/apk/res/android" packate="com.example.broadcasttest"> <uses-permission android:name="android.permission.RECEIVE_BOOT_C ...
持久化技术
持久化技术持久化技术简介数据持久化就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或计算机关机 的情况下,这些数据仍然不会丢失。保存在内存中的数据是处于瞬时状态的,而保存在存储设 备中的数据是处于持久状态的。持久化技术提供了一种机制,可以让数据在瞬时状态和持久状 态之间进行转换。
文件存储文件存储是Android中最基本的数据存储方式,它不对存储的内容进行任何格式化处理,所有数 据都是原封不动地保存到文件当中的,因而它比较适合存储一些简单的文本数据或二进制数 据。如果你想使用文件存储的方式来保存一些较为复杂的结构化数据,就需要定义一套自己的 格式规范,方便之后将数据从文件中重新解析出来。
将数据存储到文件中Context类提供了一个openFileOutput()方法,可以用于将数据存储到指定的文件中。接收两个参数:第一个参数是文件名,不能包含路径;第二个参数是文件的操作模式,主要有MODE_PRIVATE和MODE_APPEND两种模式可选,默认是MODE_PRIVATE,表示当指定相同文件名的时候,所写入的内容将会覆盖原文件中的内容,而MODE_APPEND则表示文件已 ...
探究BroadcastReceiver
BroadcastReceiver广播机制简介Android中的每个应用程序都可以对自己 感兴趣的广播进行注册,这样该程序就只会收到自己所关心的广播内容,这些广播可能是来自 于系统的,也可能是来自于其他应用程序的。而接收广播的方法则需要引入一个新的概念—— BroadcastReceiver。
BroadcastReceiver的具体用法将会在下一节介绍,这里我们先来了解一下广播的类型。 Android中的广播主要可以分为两种类型:标准广播和有序广播。
标准广播(normal broadcasts)是一种完全异步执行的广播,在广播发出之后,所有的 BroadcastReceiver几乎会在同一时刻收到这条广播消息,因此它们之间没有任何先后顺 序可言。这种广播的效率会比较高,但同时也意味着它是无法被截断的。
有序广播(ordered broadcasts)则是一种同步执行的广播,在广播发出之后,同一时刻 只会有一个BroadcastReceiver能够收到这条广播消息,当这个BroadcastReceiver中的 逻辑执行完毕后,广播才会继续传递。所以此时的BroadcastRecei ...