高级Android开发强化实战(txt+pdf+epub+mobi电子书下载)


发布时间:2020-07-11 16:48:07

点击下载

作者:王辰龙

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

高级Android开发强化实战

高级Android开发强化实战试读:

前言

在编程之余,有时候我就在想,什么样的程序员属于高级程序员呢?或者说,高级程序员有哪些特性呢?工作年限一定不是一个关键的指标,许多工作多年的程序员依然写不出优雅的程序。无论是在Android开发还是其他领域,高级程序员一定是勤奋的,可以快速地掌握大量的新技术、新框架,不仅懂得原理,还能把新的技术落地到公司的产品中去。这是衡量程序员工作能力的一个重要标准,那么怎样才能将技术运用自如呢?唯有实践。基于此,我想把自己在日常实践中的一些经典案例,编著成一本成体系的书,以便为想要进步的Android程序员增加更多的实战经验,这也是编写本书的核心目的所在。

编写本书的另外一个目的,是帮助程序员建立产品的思想,对于技术而言,孤立的存在是没有任何意义的,技术只有与需求相结合,才能具有自身的价值。技术人员在开发的过程中,要时刻了解所完成的功能可以为公司带来哪些价值,是提升用户的访问兴趣,还是提升用户的使用流畅度,抑或是其他。当以产品思维去思考技术的时候,就会有动力、有目的地学习更多有价值的技术,而不是哗众取宠地学一些“看似有用”的新技术。

除此之外,还有理解架构的本质。一些技术人员经常会问:“为什么要使用架构?这只会增加额外的代码量,而且并不会对功能或性能有所提升,只需要完成必要的开发任务即可。”这种想法是非常浅显的,因为任何一个应用都不是一次成型的,需要不断地迭代,不断地扩展,同时需要不断地修改已有的业务逻辑,这就会涉及系统兼容性的问题。如何修改新的业务逻辑而不影响旧的业务逻辑?如何最大限度地复用已有的业务逻辑?架构就是解决这类问题的钥匙,一个优秀且合适的项目架构可以保证系统的稳定性,当开发新的功能或者修改旧的功能时,不至于破坏已有的业务体系。

本书的实例都是经典实战实例,每一个例子都代表一类在开发中需要掌握的技巧。本书由浅入深地逐个讲解需要掌握的开发理论与实践,共分为七部分。

◎ 进阶基础:偏重于源码的解析和理解,介绍阅读源码的技巧,以Activity和View为例,管中窥豹地分析其中的基础知识。读者也可依据此类方法,分析其他系统组件的源码。

◎ 高阶控件:介绍若干复杂的控件布局,即AppBarLayout、CoordinatorLayout和ConstraintLayout。通过实例,让读者理解在复杂控件布局中子视图是如何组合和相互关联的。

◎ 项目架构:分析主流架构的设计思想,即Google推荐的MVP和MVVM,还有Facebook的Flux。理解这些架构是如何组织和管理大型项目的,以及它们的优点和缺点各有哪些。

◎ 响应式编程:响应式是一种编程思想,在处理网络请求和功能测试时,基于响应式框架的项目拥有更好的可扩展性和可维护性,响应式编程三剑客即RxJava、Dagger和Retrofit。

◎ 酷炫功能与精美动画:实现两个稍复杂的功能,分别是基于第三方控件和基于系统控件的扩展;并实现两个动画效果,分别用于页面展开和页面切换。对于功能和动画,不同的需求或样式层出不穷,本部分侧重于开发思路的分享。

◎ Kotlin与SVG:Kotlin是用于替代Java的高阶编程语言,SVG是用于替代PNG格式的图像技术,本书着重介绍一些基础概念,提纲挈领,以便于读者后续进行自主学习。

◎ 测试与优化:分享一个主流的自动化测试框架,以及优化内存与电量的一些常见方法。产品的性能与功能同样重要,应用的高品质也会提升产品的用户体验。这七部分几乎已经包含高级Android编程的全部内容,本书的每个部分都会通过多个实例,从不同的角度引领读者亲身实战,真正地掌握高级编程的核心开发技巧。但是,实例的数量终究有限,希望读者更多地关注于实战中的开发思想,而不是具体的代码逻辑,代码总会不断地更迭,解决问题的思维却历久弥新。本书中的实例更多的是以点带面,读者可以一边阅读和思考,一边编写代码,相信读完本书,一定受益匪浅;同时,通过本书的实例可以解决一些常见的开发需求。衷心希望每位读者在阅读完本书之后,都“不虚此行”!

将本书送给我正在怀孕的妻子,感谢你在生活和工作中给予我的支持和帮助。王辰龙2018年5月于北京海淀第1章进阶基础1.1深入剖析Activity的生命周期

在Android系统中,所有应用都是由系统提供的四大组件构成的,即Activity(活动)、Service(服务)、ContentProvider(内容提供者)和BroadcastReceiver(广播接收器),而它们之间通过Intent(意图)进行通信并相互关联。其中,Activity作为与用户打交道最为频繁的组件,承担起显示的重任,其重要性不言而喻。因此,在开发中,对于Activity的全部工作细节,需要熟练掌握。

在Android系统中使用生命周期(Lifecycle)描述组件在不同状态之间的切换。通过管理组件的生命周期实现资源的获取与释放,在不同阶段的生命周期中触发相应的回调函数,在回调函数的上层方法中,系统控制组件的创建与销毁。同样,Activity作为组件之一,也有着一套有序的生命周期,管理Activity的全部行为。

图1-1展示的是Activity的完整生命周期(图片来源于Android官网)。图1-1 Activity的完整生命周期

在系统中,有两种情况可以触发生命周期的改变,第1种是有用户参与的生命周期的改变,第2种是因为系统回收或配置修改而导致的生命周期的改变。为了更加直观地展示这两种改变生命周期的行为,本书编写了一个相关实例。通过这个实例,可以更加清晰地理解Activity的生命周期的变换形态。实例分为三个部分,将有用户参与的生命周期的变化分为因硬件导致的生命周期变化、在页面切换时生命周期的变化及由系统原因导致的生命周期的变化。

该实例的完整代码的下载地址为https://github.com/SpikeKing/wcl-activity-lifecycle-demo。1.1.1 Activity的生命周期的各种状态

在Activity中,生命周期状态主要包含6种,即onCreate()、onStart()、onResume()、onPause()、onStop()和onDestroy()。每种生命周期都代表着Activity处于不同的状态:onCreate()表示Activity的创建,onStart()表示Activity的启动,onResume()表示Activity的恢复,onPause()表示Activity的暂停,onStop()表示Activity的停止,onDestroy()表示Activity的销毁。

这些状态之间两两配对、有始有终,构成三组生命周期,相互嵌套。这三组生命周期分别为完整的生命周期(Entire Lifetime)、可视的生命周期(Visible Lifetime)及前台的生命周期(Foreground Lifetime)。

1)完整的生命周期:表示Activity组件从创建到销毁的全部过程,是最外层的生命周期。生命周期发生在调用onCreate()方法与调用onDestory()方法之间。在onCreate()的方法中,系统会创建Activity的全局状态,例如填充布局等;在onDestroy()方法中,系统会释放Activity所保存的资源。需要注意的是,onDestroy()不能保证被调用的时机,例如Activity在Activity栈中,在系统内存不足时,就可能触发强制销毁调用onDestroy()方法,而在其他情况下,只有当Activity出栈时,才会调用onDestroy()方法。

2)可视的生命周期:表示Activity组件从用户可视到离开用户视线的全过程。在这期间,用户可以在屏幕上看见当前的Activity。生命周期发生在调用onStart()方法与onStop()方法之间。在onStart()方法和onStop()方法中,执行与用户可视相关的逻辑。因为onDestroy()方法并不一定会被调用,所以在onStop()方法中,一般会执行保持当前Activity状态的逻辑。在Activity的全部存活时间中,onStart()方法和onStop()方法可能会被多次调用,这是因为Activity可能交替地由可视状态到不可视状态,再恢复到可视状态。

3)前台的生命周期:表示Activity组件显示于其他Activity组件之前,即位于Activity任务栈的栈顶,拥有最高优先级的资源使用权限,同时可以获得用户的输入焦点与用户进行交互。在可视的生命周期中,Activity组件可能位于全透明或部分透明的Activity下面,即属于可视状态。而前台状态必须位于全部的Activity之上。生命周期发生在调用onResume()方法与onPause()方法之间。在onResume()方法和onPause()方法中,执行与交互相关的逻辑。同样,在Activity的全部存活时间中,onResume()和onPause()也可能会被多次调用,即Activity可能会频繁地获取与失去焦点。

这三类生命周期循环嵌套,完整的生命周期包含可视的生命周期,可视的生命周期又包含前台的生命周期,它们共同构成Activity的生命周期体系。除此之外,还有三个特殊的生命周期状态,即onRestart()、onRestoreInstanceState()、onSaveInstanceState()。当页面从Activity栈内调至栈顶时,会调用onRestart()方法,初次创建时不会调用;onSaveInstanceState()用于储存Activity的状态信息;onRestoreInstanceState()用于恢复Activity的状态信息,仅用于系统导致的页面重建,而用户导致的页面重建需要在onCreate()中由开发者自主恢复状态信息。1.1.2 实例:准备

下面通过实例,让我们更好地理解生命周期的状态切换。实例分为三个部分:因硬件导致的生命周期变化、在页面切换时导致的生命周期变化、由系统原因导致的生命周期变化。在讲解实例之前,先展示本实例的运行环境,以便读者更好地理解与执行代码,本书其他实例的运行环境与此实例类似。动手实践是学习编程的不二法门,也是成为高级程序员的必要条件之一。

1.硬件环境

实验真机为Redmi Note 4X,即红米Note 4X;操作系统为Android 6.0。

实验模拟器:操作系统为Android 7.1.1,如图1-2所示。图1-2 模拟器(开发电脑:MacBook Pro 10.11.6)

IDE(Integrated Development Environment):Android Studio 2.3.2,如图1-3所示。图1-3 IDE

2.软件环境

Android Tools 的 Gradle 版本为2.2.3,位于根目录下的build.grale文件中

Android 的 Gradle 构建版本为2.14.1,位于根目录下的

Android SDK 版本为24,位于项目目录下的/app/build.gradle中:

全部实例代码都已经通过测试,从网络下载后,运行项目即可使用。读者在阅读本节时,需要提前下载源码,并调试通过,根据所讲述的内容运行代码,通过实战更好地学习本节知识。1.1.3 实例:因硬件导致的生命周期变化

我们在使用应用的过程中,除在应用内的交互外,通过手机的硬件按键,也能触发生命周期的改变。对于应用内的交互会导致页面的切换,则触发常规的生命周期状态的改变,从onCreate()到onDestroy()依次调用,这是基本的生命周期变化。除此之外,还需重点关注一些特定的硬件操作,比如用户按手机的菜单(Home)键和后退(Back)键。

对于一款基本的Android手机而言,手机底部都会包含两个基础的按钮,一个是位于中部的菜单键,另一个是位于右侧的后退键。因此,除了在应用内提供的交互场景,用户最常用的两种操作就是按菜单键或后退键。那么这两种常用的操作又会给Activity带来哪些生命周期的变化呢?下面通过实例来讲解。

先来看看应用的主页 - MainActivity.java,通过源码来分析这个Activity页面是如何组成的,如图1-4所示。图1-4 MainActivity

首先,声明TAG标签,作为Log输出的标签,用于在Logcat中过滤信息;使用ButterKnife插件,声明两个按钮,用于页面的跳转;声明EXTRA_TEXT标签,用于在Activity中模拟状态的存储。对于字符串静态常量,一般使用大写字母加下画线的形式表示。

代码如下:

注意:ButterKnife是由Jake Wharton编写的一个用于声明布局中控件的插件,代替调用findViewById()方法,节省了大量的开发时间。在项目目录中,添加ButterKnife的依赖即可使用。具体原理与使用方式可参考ButterKnife的官方网址https://github.com/JakeWharton/butterknife。

其次,onCreate()方法作为创建Activity的第一个调用函数,负责初始化Activity的全部行为,我们一般重点编写代码逻辑的部分。例如setContentView(),设置页面布局;ButterKnife.bind(),负责绑定ButterKnife并初始化,只有在初始化ButterKnife之后,才能调用Bind()标注进行布局ID的绑定;设置mBTranslucent按钮和mBSecond按钮的绑定事件;获取EXTRA_TEXT的状态存储信息及输出onCreate()方法的调用提示。在每个生命周期方法中,都添加了相应的调用提示,方便在Logcat中观察当Activity页面改变时,生命周期变化的整个过程。

代码如下:

再次,在Activity的启动过程中,先调用onCreate()方法,然后依次调用onRestart()、onStart()、onRestoreInstanceState()、onResume(),其中onRestart()与onRestoreInstanceState()并不是每个生命周期都会调用的。

代码如下:

最后,在Activity的关闭过程中,依次调用onPause()、onSaveInstanceState()、onStop()、onDestroy(),其中onSaveInstanceState()并不是每个生命周期都会调用的,只有页面完全不可视时才会调用,用于储存当前页面的状态,如果仅仅失去焦点则不调用。

代码如下:

最终MainActivity页面的显示如图1-5所示。图1-5 MainActivity页面

在页面初次启动时,MainActivity页面执行的生命周期依次为onCreate()、onStart()、onResume(),都是常规的生命周期流程。在执行onResume()方法之后,MainActivity页面已经具备与用户交互的功能。

在按后退键时,MainActivity页面执行的生命周期依次为onPause()、onStop()、onDestroy(),也都是常规的生命周期流程。在执行onDestroy()方法之后,MainActivity页面已经完全销毁。

但是,如果没有按后退键,而是按菜单键,MainActivity页面仅仅是由前台转入后台,并不会立即执行销毁。当用户再次使用时页面仍可快速启动。但是系统可能会在某个时刻自动销毁这个页面,如内存不足,这是Android系统的机制,防止后台页面过多,影响系统效率。

在按菜单键时,MainActivity页面执行的生命周期依次为onPause()、onSaveInstanceState()、onStop(),不会执行onDestroy()方法,也就没有释放系统资源,保证在下次启动时,仍可快速加载。调用onSaveInstanceState()方法的原因是系统可能在后台自动杀死当前Activity,所以需要保存当前页面的状态,如果系统这样做,再次调起页面时,系统也会自动调用onRestoreInstanceState()恢复当前状态。在执行onStop()方法之后,MainActivity页面已经由前台转入后台,对用户不可视。

在系统桌面中再次点击应用图标,应用又恢复为可交互状态,MainActivity页面执行的生命周期依次为onRestart()、onStart()、onResume()。由于间隔时间较短,系统资源较为丰富,系统未执行onDestroy()方法,强制杀死当前Activity,所以不需要调用onCreate()方法进行页面创建,也不需要调用onRestoreInstanceState()方法恢复状态。1.1.4 实例:页面切换时的生命周期变化

对于非透明页面,Activity的逻辑比较固定,执行完整的生命周期,但是对于透明页面略有不同,因为透明页面作为底部页面的浮层,底部页面仍然可视,所以不会执行销毁逻辑。为了验证全部的生命周期过程,下面通过实例,创建非透明和透明两个页面,验证在Activity页面切换时生命周期的变化情况。

基本的生命周期逻辑:在onStart()时,Activity页面对于用户可视,但是无法交互;在onResume()时,Activity页面不仅可视,而且可以交互,因此onResume()在onStart()之后触发;在onPause()时,Activity页面无法交互,而且必须在Activity页面的onPause()执行完成后,下一个Activity页面才能执行启动逻辑,如onCreate()或onResume();在onStop()时,Activity页面对于用户不可视。

注意:在onPause()中,不能执行复杂的操作,否则会影响下一个Activity的启动速度。

从非透明页面讲,首先创建一个简单的非透明页面,此页面的创建生命周期仅含有onCreate(),销毁生命周期全部包含,即onPause()、onStop()、onDestroy()。

首先,执行在MainActivity中启动非透明页面SecondActivity,即由当前Activity页面切换至另一个非透明的Activity页面,导致当前页面销毁,新的页面被创建。在MainActivity页面的onPause()执行完成后,SecondActivity页面才能执行启动逻辑,SecondActivity启动完成后,才会执行MainActivity页面的剩余销毁工作,如onSaveInstanceState()和onStop()。因为当前Activity页面仍在Activity栈中,并未出栈,则并未执行onDestroy()的方法。

注意:对于onSaveInstanceState()方法,在页面关闭时都会执行,但是非系统原因的关闭,不会执行默认的恢复数据操作,即onRestoreInstanceState()方法。

接着,关闭SecondActivity页面,重新返回MainActivity页面。因为MainActivity页面并未被销毁,即未执行onDestroy()方法,所以无须重建,执行onCreate()方法,只需要执行onRestart()、onStart()、onResume()方法即可。同样,在SecondActivity执行onPause()方法之后,MainActivity才开始自身的创建工作。因为SecondActivity位于Activity栈的栈顶,所以触发出栈操作,页面完全销毁,所以执行onStop()完成之后,会继续执行onDestroy()方法。

启动一个透明页面。透明页面的特点是在启动之后,底部页面仍然可视,因此系统执行Activity生命周期的逻辑也有所变化。为了保证生命周期的逻辑清晰,透明页面与非透明页面的逻辑相同,生命周期状态仅显示onCreate()、onPause()、onStop()、onDestroy()等。

唯一不同的是,在透明Activity的声明AndroidManifest.xml文件中,使用透明主题样式。

透明主题样式如下:

最终透明的TranslateActivity页面的显示如图1-6所示,按后退键即可关闭。

首先,在MainActivity中,启动透明页面TranslateActivity。在启动透明页面时,MainActivity页面仅仅执行onPause()方法,与非透明页面不同,并不会继续调用onStop()方法。因为onPause()方法控制MainActivity是否具有交互功能,onStop()方法控制MainActivity是否可视,所以MainActivity透明页面TranslateActivity,仅仅使其自身失去交互功能,并未影响其是否可视。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载