Android程序猿必看之《终端应用开发指南》

Posted showCar

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android程序猿必看之《终端应用开发指南》相关的知识,希望对你有一定的参考价值。

一、前言

4G移动网络的商用为移动互联网的蓬勃生长提供了肥沃的土壤,并协同国内外众多互联网厂商及终端厂商共同引领了中国移动互联网翻天覆地的发展与创新。

2014年以来移动4G用户数目显著提升,拉动了全网用户的流量增长,同时随着流量资费的下降,运营商将与优秀APP互助互惠:更充足更宽带宽的数据业务促进用户对移动终端APP的使用,而优秀的APP则会拉动移动互联网流量的进一步增长。

2016年中国智能手机用户预计将达6亿以上,智能手机已经并将进一步渗透至人们生活中的方方面面。根据2014年数据,中国移动终端用户平均安装34款应用,单台终端平均每日下载应用3款以上,打开应用可达20款,用户每日使用APP的时间也持续增加。作为移动互联网的入口,APP的质量优秀与否已成为用户对移动互联网体验的重要影响因素。

2014,GooglePlay商店的应用数量已达143万,开发者数量已达38.8万。如此规模巨大的市场吸引大量开发者及团队的加入,带来了空前的繁荣与竞争。如何在规模成百上千的竞品当中脱颖而出,一方面需要优秀的运营团队及策略,而更能起到决定性作用的是APP本身的品质。《终端应用开发指南》将从网络、终端与APP协同工作的角度出发,基于android平台,对如何开发出优质的APP从而为用户提供更卓越的互联网使用体验给出参考建议。

二、如何定义优秀的APP

对于一款优秀的APP,“可用”是基本前提,“好用”是脱颖而出的必要条件,安全则是保护用户权益的根本保障。

“可用”:移动终端设备尤其是Android手机的高度碎片化给应用的兼容性带来了巨大挑战。这一碎片化既包括硬件配置如芯片平台、显示屏幕等,更涉及了极为丰富多样的操作系统。完善的兼容性成为了保证用户使用体验、提升APP质量的重要因素。

“好用”:相比于PC等传统终端设备,移动终端设备能力虽然已得到极大的提升,但内存、电量等资源依然格外宝贵。在各类APP层出不穷的当下,一款APP仅仅做到“可用”还远远不够。

“安全”:移动应用迅速覆盖了包括出行就餐、日常起居、甚至金融理财等各个领域。然而凡事有利有弊,Android漏洞、APP安全早已饱受诟病。应用安全已经成为用户挑选应用产品甚至挑选应用商店的决定因素。如何保护用户的数据安全及权限安全成为了开发者需要研究的重要课题。

移动终端产品与时俱进,已成为普罗大众眼中高新科技的代言词,也渐渐成为大众日常使用的最具科技感的个人电子设备。在“可用”“好用”“安全”的基础上,应用开发者们应不断扩展视野,并充分整合已有的最新资源,在广度上覆盖更多的移动终端产品,在深度上不断挖掘移动终端的各项能力,为用户提供更多。

本文将主要围绕着“可用”“好用”“安全”“新技术”四方面展开。第三章从操作系统版本、屏幕分辨率等方面对常见的问题进行了阐述,并抛砖引玉,给出了解决部分问题的参考建议。第四章将分别从系统资源、功耗、网络性能以及APP的交互设计等几个方面对已有的问题进行阐述并提供建议。第五章强调了安全的重要性以及如何去保证安全,将从数据安全、权限安全以及内容安全等方面对问题进行阐述并给出相应问题可供参考的解决办法。第六章主要从终端新能力、网络新技术以及终端新趋势三个方向进行介绍。

三、让APP能被每一个用户使用

终端市场发展迅速,蓬勃的市场带来了市面上千百款终端巨大的差异性。一方面,用户需求变更及科技的快速发展推进终端的硬件及操作系统的迭代更新;另一方面,各终端厂商为打造自身品牌体现产品的差异化,对外观及操作系统进行大量的、深度的个性化定制。显著的差异化给APP开发者的适配工作带来了巨大的挑战,完善的兼容性成为了保证用户使用体验、提升APP质量的基本要素。

3.1 丰富多样的操作系统

根据最新统计,2014年至2015年第三季度国内销售智能终端各操作系统占比如下图所示。

2015第三季度销售的ios及Android终端占比之和已超过95%。2015年Android占比虽有所下降,但依然占据主导地位,占比高达80%以上。

为了充分开发硬件能力、满足用户需求并提升用户体验,Google周期性推出新操作系统版本更新,并不定期进行小版本升级。相对而言,由于终端硬件的不支持或用户基于自身喜好不倾向于更新系统,终端产品无法保证操作系统同步更新至最新版本,这导致了市面上同时存在多个操作系统版本的问题。相比于iOS,Android由于其开放特性,使越来越多的终端厂商加入其阵营当中,愈发加剧了Android系统的碎片化。2015年第三季度在网终端产品及国内销售终端产品Android版本占比分别如下所示:

目前在网Android手机搭载的操作系统中小版本多达20个以上,其中大版本仍以4.X为主,但2015年第三季度销售的Android手机搭载的操作系统中5.0版本已占较大比例,4.4及5.0二者占比共计76.74%。

Android阵营的碎片化不只体现在系统版本,更体现在了各终端厂商及互联网公司定制化系统的多样性。2015年以来国内销售终端搭载的定制系统多达36款,如MIUI、EmotionUI、Flyme等,若考虑个人爱好者开发的相对小众的产品,定制系统的种类将更是数不胜数。厂商因为各种各样的原因修改了Android系统的API,带来部分APP无法安装、运行出错、强制退出等问题,给APP的适配带来了极大困难。

通过对海量测试数据深度的收集整理与分析,这里总结了最为常见的适配问题并提出了相应的解决方案:

1. 在低版本Android系统上调用高版本API导致应用Crash

在不断升级的过程中,Android为支持新的功能和特性需增添新的API。开发者如果在应用内调用了此类API,同时没有限定应用最低支持版本,则在低版本上运行时会出现崩溃异常。

当Android发布新版本,开发者一方面要重点关注Google新增的功能,另一方面要关注新增功能所使用的API是否为新增。如果应用在迭代升级的过程中使用了新增功能或函数,那么应用开发过程中一定要注意新增功能在低版本Android系统上实现的兼容性。

2. 使用Android官方废弃函数导致应用不兼容新版本

在Android版本更新的过程中,不仅仅会增加新的函数,也会由于需求的变更或基于执行效率的考虑而删除部分函数。开发者在APP开发过程中,如果未能及时跟进和更新应用中相应功能实现,应用在新版本系统上调用已经删除的函数,运行时候就会出现崩溃异常。

3. 由于厂商定制系统导致的不兼容问题

Android系统的开放性吸引了大量的终端厂商加入其阵营当中。基于产品的差异化需求,直接使用Android原生系统的终端厂商寥寥无几,很多厂商在定制系统中对应用程序框架层有或多或少的改动。

如部分厂商在定制系统时修改存储卡的挂载点,如果APP开发代码中使用硬编码定义存储卡路径就会出现无法读取和保存文件的情况。应尽量避免使用硬编码定义存储卡路径,使用Environment.getExternalStorageDirectory()等对应API获取。

3.2 千差万别的屏幕

屏幕分辨率发展迅速,在2014年下半年2K屏幕已经成为了各厂商旗舰机的主流配置。更清晰的屏幕给用户呈现更丰富的内容,也带来了更惊艳的视觉享受。短短5年,手机屏幕分辨率从800×480骤增至2560×1440。当前主流的屏幕分辨率包括WVGA(800×480)、qHD(960×540)、HD(1280×720)、FHD(1920×1080)、WQHD(2560×1440)等。2014年至2015年第三季度销售终端的屏幕分辨率的占比如下:

由上图可以看出,在屏幕分辨率保持多样性的同时,FHD、WQHD等高分辨率屏幕的占比正在提高,针对高分辨率屏幕开发高清APP已是目前趋势。 
- 为确保APP对不同分辨率屏幕的良好兼容,应着手于AndroidManifest.xml文件及res目录下文件的配置。

1. AndroidManifest.xml设置

在AndroidManifest中添加子元素android:anyDensity=”true”后,应用程序安装在不同密度的终端上时,程序会分别加载xxhdpi、xhdpi、hdpi、mdpi文件夹中的资源,其中dpi表示屏幕像素密度,指每英寸上的像素点数。之前还有ldpi,但是随着移动设备配置的不断升级,现在适配时不需考虑。mdpi、hdpi、xhdpi、xxhdpi用来修饰Android中的drawable文件夹及values文件夹,用来区分不同像素密度下的图片和dimen值。

在开发过程中,应将合适大小的图片放在合适的文件夹中,对于五种主流的像素密度(MDPI、HDPI、XHDPI、XXHDPI和XXXHDPI)应按照 1:1.5:2:3:4的比例进行缩放:

1. 横屏竖屏目录区分

在开发过程中,应分别对横屏及竖屏建立不同的目录,放置适用于横屏及竖屏的图片及布局文件,适应横竖屏的切换。如在res目录下建立layout-port和layout-land两个目录,里面分别放置竖屏和横屏两种布局文件。

2. 关于布局的适配建议

1) 尽量不使用绝对布局。 
2) 尽量使用match_parent而不是fill_parent。 
3) 使用layout_weight属性按屏幕比例布局,这样可以保证在屏幕上面展示的时候有合适的大小。不要使用像素单位的硬编码,需要的话在dimens定义使用。 
4) 设置android:layout_width和android:layout_height的值时,dp比px更好,文字大小应该使用sp来定义。 
5) 为适应不同屏幕分辨率,在res目录下创建不同的layout文件夹,比如:layout-1280x720、layout-1920x1080等,Android系统会根据屏幕的分辨率大小选择合适的layout进行使用。

3.3 版本迭代的兼容

用户的需求不断革新,快速迭代已成为APP成功的因素之一。根据测试数据,移动应用平均每月会进行一次新版本的升级。如此频繁的版本升级使得高低版本间的兼容性尤为重要。

若要保证高低版本间不出现兼容性问题,首先要设置好版本号(VersionCode)的值。VersionCode是一个Integer类型的值,在第一次发布应用到市场时,版本取值为1(VersionCode=1),这也是目前典型和普遍的做法。然后,发布更新版本时可以递增VersionCode的值。

APP版本迭代时,新功能需求引起数据库的变动,需要重写SQLiteHelper的update方法对数据库进行增量更新,避免删除所有数据表再重新创建。

另外,在APP升级过程中要确保旧版本的可用性,保留服务端旧版本接口相关代码支持。对于过于老旧的计划不再支持的版本,要推送消息指引用户主动进行版本更新。

四、让手机更轻松,增强用户体验

相比于PC等传统终端设备,移动终端设备的资源更加宝贵:系统及硬件资源决定了用户使用体验;续航已成为影响用户挑选终端的重要指标;复杂的网络环境也让用户对流量格外关注。

是否可以通过降低APP占用的系统及硬件资源有效延长终端使用时间?是否能够在保证提供有效服务的同时降低流量的消耗?是否可以为用户提供更顺畅更快捷的操控体验?以上已成为APP从“可用”到“好用”的分水岭,也成为衡量开发者及团队是否专业的重要标志。

4.1 良好的编程习惯

在资源使用方面,如果打开了资源,要记得关闭资源。要尽量晚地获取,尽量早地释放。如果使用了底层的设备服务时更应如此。当不再需要这些信息时要取消获取最新信息的注册。这将帮助避免不必要地耗费设备电池电量或占用系统资源。

另外,作为一名优秀的开发者,也要学会充分利用调优工具。

Android SDK随带了许多工具,可用来对应用程序进行分析,比如:Android Lint:Android Lint是SDK Tools 16 (ADT 16)之后才引入的工具,通过它对Android工程源代码进行扫描和检查,可发现潜在的问题,以便程序员及早修正。由于Android Lint在最初设计时就考虑到了独立于IDE,所以它可以很方便的与项目中的其他自动系统(配置/Build/测试等)集成。

TraceView:这款图形化工具可以帮助调试和找到应用程序中的性能瓶颈。

学会使用这些SDK提供的调优工具可以在开发工作中起到事半功倍的作用。

4.2 更低的系统资源占用

CPU与内存是决定终端性能的最重要的两部分硬件。手机芯片的处理能力飞速提升,从2012年到2014年两年的时间内走完了PC从1999年到2006年的历程。虽然移动终端的性能提升显著,但终端的硬件资源依然有限。随着高CPU及内存占用率的APP层出不穷,给终端带来了更大的负担,容易造成手机运行卡顿等现象,因此用户越发重视APP对CPU及内存的占用率。降低Android系统及单个APP的资源占用以获取更充裕的空闲资源,可以给用户提供更丰富的功能与服务并带来更流畅的操控体验。

2015年,移动终端芯片产品开始进入64位时代,核心数目越发集中于四核及八核。相比于芯片的性能,厂商越发重视能效,即在性能平稳提升的同时更重视能耗的降低。

市场销售终端CPU主频变化趋势如下图所示: 

由上图可以看出,CPU主频提高的趋势依然存在,但变化已渐平缓。芯片厂商将更多的精力用于架构与工艺的提升。市场主流销售终端的CPU核心数目变化趋势如下:

8核处理器的市场占比逐月提升,部分8核处理器采用big.LITTLE架构模式,通过两种架构双四核的合理调度有效降低功耗。

2014至2015年第三季度,国内市场销售终端内存占比如下:

目前市场主流内存大小从14年的1GB及2GB增长至2015年的2GB及3GB。由于手机产品的精品化趋势,2GB及2GB以上的内存大小已在2015年成为主流,各大终端厂商的旗舰机型则相继使用3GB甚至更大的内存。

RAM在任何软件开发环境中都是很宝贵的资源。开发者以及普通用户们越发认识到降低APP资源占用的必要性。在Android系统中,每个程序都会有可使用的内存上限,即堆大小(Heap Size)。随着硬件设备的升级,堆大小也随之提高。在开发应用程序时所使用的内存不能超出限制,否则会出现OutOfMemoryError。

虽然Android系统具有GC操作且在绝大多数情况下我们并不需要主动通知系统进行GC,但这并不意味着可以忽视内存分配与释放的时机与地点。

为了降低终端硬件资源的占用,以下建议可供参考:

1. 珍惜Services资源

如果应用需要在后台使用Service,除非它被触发并执行一个任务,否则Service都应该是停止状态。另外需要注意当Service完成任务之后,因为停止Service失败而引起的内存泄漏。当启动一个Service,系统会倾向为了保留这个Service而一直保留Service所在的进程,系统无法把Service所占用的RAM空间腾出来让给其他组件。另外,Service不能被paged out,这减少了系统能够存放到LRU缓存当中的进程数量,它会影响APP之间的切换效率,甚至会导致系统内存使用不稳定。

限制Service的最好办法是使用IntentService,它会在处理完交代给它的intent任务之后尽快结束自己。

2. 当UI隐藏时释放内存

当用户切换到其它应用并且原应用 UI不再可见时,应该释放原应用UI上所占用的所有内存资源。在这个时候释放UI资源可以显著的增加系统缓存进程的能力,它会对用户体验有着很直接的影响。

3. 当内存紧张时释放部分内存

在APP生命周期的任何阶段,通过onTrimMemory的回调方法同样可以得知整个设备的内存资源已经开始紧张。应该根据onTrimMemory回调中的内存级别来进一步决定释放哪些资源。

4. 使用优化的数据容器

利用AndroidFramework里优化的容器类,如SparseArray、SparseBooleanArray与LongSparseArray。通常的HashMap的实现方式更加消耗内存,因为它需要一个额外的实例对象来记录Mapping操作。另外,SparseArray更加高效,这在于他们避免了对key与value的autobox自动装箱,并且避免了装箱后的解箱。

5. 为序列化的数据使用nanoprotobufs

Protocol buffers是由Google为序列化结构数据而设计的,一种语言无关、平台无关、具有良好扩展性的协议,类似XML却比XML更加轻量、快速、简单。如果需要为数据实现协议化,应该在客户端的代码中使用nanoprotobufs。

6. 谨慎使用第三方Library

很多开源的library代码都不是为移动网络环境而编写的,如果运用在移动设备上效率并不高。当使用一个第三方library的时候,应该针对移动网络做繁琐的迁移与维护。即使是针对Android而设计的library,也可能是很危险的,因为每一个library所做的事情都不同。

7. 使用ProGuard来精简代码

ProGuard能够通过移除不需要的代码,重命名类、域与方法等对代码进行压缩、优化与混淆。

8. 对最终的apk使用zipalign

在编写完所有代码,并通过编译生成apk之后,需要使用zipalign对apk进行重新校准。

9. 合理使用多进程

通过把APP组件切分成多个组件,运行在不同的进程中,可以有效提高内存管理的灵活度及效率。这个技术必须谨慎使用,因为如果使用不当,它会显著增加内存的使用,而不是减少。

4.3 更低的耗电量

终端的性能经历了翻天覆地的提升,移动互联网的发展也让终端承载了越来越多的任务,然而随着终端各项业务对能耗需求的增加,移动终端限于体积却无法大量地提升电池的容量。电池容量虽有所提升,但在日常使用中依然捉襟见肘,手机续航问题长久以来困扰着终端厂商与用户。下图为2014年至2015年第三季度国内市场销售终端的电池容量占比变化情况:

由4.2节对芯片发展趋势的分析可以看出,为了降低终端的耗电量,硬件厂商已经做出了切实的努力。与此同时,目前市面大多数的移动终端产品所搭载的操作系统也都带有省电模式:通过降低屏幕亮度、CPU限频、关闭后台等方式降低电量消耗。

硬件及操作系统都已为移动终端的能耗降低做出了贡献,在应用层级也应采取必要的方式节省能耗。

1. 合理安排任务

可以通过BatteryHistorian Tool查看详细的电量消耗,如果发现APP有电量消耗过多的问题,可以使用JobScheduler API来对一些任务进行定时处理,如把任务重的操作等到手机处于充电状态,或是连接到WiFi的时候来处理。

2. 汇集零散的网络请求统一进行操作

触发网络请求的操作,每次都会保持无线信号持续一段时间,可以把零散的网络请求打包进行一次操作,避免过多的无线信号引起的电量消耗。

3. 减少网络传输的数据量

在没有必要的情况下不要联网进行操作,合理使用ImageLoader,使用增量更新,或者在满足质量的情况下,对数据进行一定的压缩 (和缓存合并)。

4. 优化APP心跳机制

APP应通过自适应等方式优化心跳机制,减少不必要的心跳。这将有利于终端电量的节省。关于心跳机制的具体内容将在4.4节做更详细的阐述。

4.4 更优的网络性能

2014年以来4G的网络建设和商用为用户带来更高速的数据通讯体验,而绝大多数用户限于费用而对应用产生的流量较为敏感,尤其是对于后台流量更是谨而慎之。

2015年9月在网用户月均使用流量243.37MB,逾75%的用户每月使用流量在200MB以下。相对而言,为了保证用户使用体验,一些APP开发者以耗费不必要的网络流量为代价,频繁交互信息或过度强化心跳机制,导致用户的流量费用和电量均损耗较大。如何在消耗较少流量的同时提供有效服务并对后台流量进行有效控制成为了开发者、终端厂商以及运营商共同关注的重要课题。

为了降低流量并提高网络性能,可以从优化心跳机制及数据获取过程两方面着手:

1. 优化心跳机制

不同类别应用的心跳周期存在差别,而同一类别下不同应用的心跳周期也不尽相同。

根据测试,某终端待机底电流为4.9mA,后台同时运行微信、QQ、飞信这三个典型即时通信应用,55分钟待机时间内有47次心跳包,心跳间隔不均匀,平均心跳包间隔70s,平均待机电流22mA,接近待机底电流的5倍。

智能终端普遍会同时运行多个应用,由于各应用独立发送心跳包,导致心跳包非常密集,从而带来终端电量和流量的大量消耗。

心跳一方面影响终端的功耗,更对运营商的网络存在影响。下图是一次业务心跳导致的信令交互过程,空闲状态时的业务心跳包触发终端发起服务器请求过程,引起随机接入→安全模式→无线资源重配→无线链路释放等过程。

单用户同时有多应用程序在后台运行时,每个应用业务都各自维护心跳包,导致心跳包间隔相对单应用来说大大缩短。假设应用业务心跳包间隔60s,则每60s单用户发送8条RRC信令,占用12-16次物理下行链路控制信道(PDCCH),占用5-8次物理混合ARQ指示信道(PHICH),至少占用一次随机接入信道(PRACH)。以下是关于信道承载能力的分析:

计算基于如下现网常用配置:20M系统带宽,上下行配比3DL:1UL,特殊时隙配比10:2:2,PCFICH取值3,PHICHNg参数取值1/6,PRACH配置为10ms一个PRACH资源,公共preamble个数配置为52。

1) PDCCH:以平均聚合等级为4估算,10ms内可用PDCCH个数为6(常规子帧)*21+2(特殊子帧)*13=152个,则每秒能够承载的PDCCH个数为15200次,每60秒能够承载的PDCCH个数为912000次。

2) PRACH:每10ms共有1次PRACH资源,每PRACH资源可复用52个用户,不考虑冲突,则每秒支持用户数为5200,每60s支持用户数为312000。

3) PHICH:PHICH组复用用户数按最大值8估算,则每子帧支持PHICH用户数为24,则每秒支持用户数为4800,每60s支持用户数为288000。

此外频繁的心跳包还可能导致终端一直处于RRC连接态,耗费系统的PUCCH(CQI、SR)、SRS等资源,导致系统容量下降,同时也会导致终端耗电增加。

智能终端各类软件所引发的无线信令流量是传统非智能终端的10倍以上,这进一步增加了智能手机产生的信令。同时,必然会影响终端与网络之间的空中接口的信令处理能力,那么一旦信令信道发生拥塞,就会导致空口资源的调度失控。这时即便空口资源是空闲的,终端也无法使用。也很容易引发雪崩效应,当终端申请不到空口资源或链接不上网络就会不断重试,导致信令信道更加拥塞。对用户来说,这将会导致用户掉话率提高、发送消息延迟、甚至无法接听拨打电话。

绝大多数移动应用都是通过TCP长连接来进行Push消息的,TCP长连接存活,消息Push就及时。

为了保证接收消息的及时性,当APP处于前台活跃状态时,建议使用统一的固定心跳。而当应用进入后台时,建议使用不同于前台运行时的周期更长的心跳策略。通常情况下,建议在后台自适应计算心跳周期,根据自身产品的特点和当前的网络环境选择合适的心跳范围。

1) 统一心跳包的发送

理论上即时通讯类应用所需的心跳周期是最短的,当前即时通讯类应用心跳周期在4min左右。

建议将最小需求4min作为基础周期,各应用心跳包发送周期设置为基础周期的整数倍,如8min、12min,如此基本满足大多应用需求。以终端上的时钟为参考系,当分针指向0、4、8、…56时,需要发送心跳的应用将心跳包统一发送。

2) 优化心跳包发送周期

用户可根据需求自主选择心跳发送周期,允许用户在省电、及时等多个场景间切换。根据网络环境、用户使用情况试探性地动态调整发送周期,如从4分钟试探调整至8分钟、12分钟、16分钟。终端休眠时应用的心跳发送周期应延长,如调整至亮屏状态时的二倍。

2. 优化数据获取

在获取数据的过程中,建议的优化策略包括:

1) 连接复用。通过如开启keep-alive的方式节省建立时间。对于Android来说默认情况下HttpURLConnection和HttpClient都开启了keep-alive。

2) 请求合并。即将多个请求合并为一个进行请求。

3) 减小请求数据大小。为了减小请求数据的大小,可以尝试使用对请求头进行压缩的方式。而对于POST请求,Body也可以做Gzip压缩。

4) CDN缓存静态资源。缓存常见的图片、JS、CSS等静态资源。

5) 减小返回数据大小。为了减小返回数据的大小,一般可以采用对返回数据进行压缩的方式。另外使用JSON代替XML、WebP代替其他图片格式等精简数据格式的方式也可以减小返回数据的大小。对于不同的设备及不同的网络环境要有区别地返回内容:如不同分辨率的图片。需要数据更新时,可以考虑增量更新,如常见的服务端进行bsdiff,客户端进行bspatch。

6) 数据缓存。缓存获取的数据在一定的有效时间内再次请求可以直接从缓存读取。

4.5 更优的交互设计

APP内容的加载时间往往是影响用户满意度的重要因素。内容加载时间主要取决于用户所在的网络环境,而通过良好的交互设计尤其是加载页面的设计,可以有效降低用户的等待感,让用户“不烦躁”地等待。

1. 用非模态的加载方式

尽量使用非模态的加载方式,就是加载的过程是不打断用户,不需要等待加载完就可以进行其他操作,如下示意:

用非模态的加载方式,用户可以利用做其他事情来打发等待的时间,而不用一直等待数据加载完成,大大降低了等待的焦躁感。即便是模态的加载,也要给一个取消的选项,当用户不耐烦的情况下可以取消。

2. 情趣化的加载动画

加载的过程如此枯燥乏味,有创意的设计师们可以设计了各种有创意的加载动画。这些加载动画让等待的过程变成了一种享受,用户能感受到设计师的情怀,体会新鲜有趣的等待过程。提升了产品情趣化的设计语言,让等待的焦躁感一扫而空。

3. 漫长加载告知进度

如果是时间较长的加载过程,最好能清晰的告知过程进度,这时候就需要采用有进度的加载设计。浏览器的进度条是一种较为常见的进度告知设计,通过这个进度告知,让用户有了更加明确的知情权,也能更好的预期到加载完成的时间。

4. 尽量提前加载

尽可能的利用预加载或有WiFi的情况下离线缓存的方式,把内容提前加载下来,这样能做到最大限度的降低加载给用户带来的卡顿感。如果能判断出来用户下一步要做的事情,提前帮用户加载相应的内容,肯定是最符合需求场景的事情。

4.6 其他注意点

1. 注意避免发生ANR问题

ANR: Application Not Responding,即应用无响应。为了尽量避免ANR错误,在编码上有以下三点建议:

1) UI线程尽量只做跟UI相关的工作,避免在主线程(UI线程)上进行复杂耗时的操作,比如说进行大量的计算/操作数据库/读写文件等。这类复杂耗时的操作可以通过使用AsyncTask或者使用多线程来实现。

2) BroadCastReceiver要进行复杂操作时,可以在onReceive()方法中启动Service来处理。

3) 在设计及代码编写阶段避免出现同步/死锁或者错误处理不恰当等情况。

2. 避免过度绘制

1) 太多重叠的背景:检查在布局和代码中设置的背景,有些背景是被隐藏在底下而永远不可能显示。这种没必要的背景一定要移除,因为它很可能会严重影响到APP的性能。

2) 太多重叠的view:必要的时候尽可能动态地加载布局,只有用到重叠的view的时候才进行加载,推迟加载的时间,而不是所有的都通过SetVisiblity函数来控制。

3) 复杂的Layout层级:添加到应用中的每一个控件和布局文件都需要经过初始化、排列位置和绘制三个过程,因此使用嵌套的线性布局可能导致布局层级变得十分冗余。复杂的布局,既会提高我们的设计难度,也会降低代码效率,因此,不妨多使用一下相对布局。建议使用HierarchyViewer工具来分析和优化布局,要尽量减少布局中的枝叶,减少父母层级,避免过深的布局层级。

3. 避免空指针

空指针引起的原因主要有调用空对象的方法、访问或更新空对象的变量、获取空集合的长度、访问或更新空集合中的内容、抛出空的Throwable对象、同步空对象等。为避免空指针,应当在使用之前确保对其做了适当的初始化。

五、千万别忽视安全

2015年,中国移动互联网用户数已突破9亿。随着移动互联网的高速发展,智能手机、平板电脑以及智能穿戴设备等已经充斥了人们的生活,移动应用迅速覆盖了包括出行就餐、日常起居、金融理财等各个领域。

然而凡事有利有弊,Android漏洞、APP安全早已饱受诟病。2015年第二季度,工业和信息化部组织对40余家手机应用商店的应用软件进行技术检测,发现存在问题的应用软件达80款,涉及违规收集用户个人信息、恶意扣费、强行捆绑推广其他无关应用软件等问题。安全性成为了用户选择APP的重要参考条件。

5.1 保护用户的数据

与iOS相比,Android提供了一种开放的环境,在获得了灵活性、可以满足各种定制需求的同时,也损失了部分安全性。APP开发团队通常将精力集中在产品设计、功能实现、用户体验和系统效率等,而忽略了安全问题,导致数据存储以及通信过程中存在漏洞,给恶意攻击者们留下了可乘之机。

1. 数据存储安全

APP的存储区域分为外部(SD卡)和内部(NAND闪存)两种。除了大小和位置不同之外,两者在安全权限上也有很大的区别。外部存储的文件没有读写权限的管理,所有应用软件都可以随意创建、读取、修改、删除位于外部存储中的文件,仅仅需要申明READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限。内部存储则为每个软件分配了私有区域,并有基于Linux的文件权限控制,其中每个文件的所有者ID均为Android为该软件设立的一个用户ID。通常情况下,其他软件无权读写这些文件。

为了保护用户存储数据的安全,有以下建议可供参考: 
1) 避免将数据明文保存在外部存储 
APP可能将系统数据及用户数据存储在外部存储(SD卡)上。当这些数据是直接明文保存的,攻击者可以对这些数据进行读取,造成隐私信息泄露。若恶意软件读取了系统数据则可能会展开进一步的攻击。

更好的处理方法是对这些数据进行加密,相对敏感的信息如密码保存在内部存储,由系统托管或者由用户使用时输入。

2) 将软件运行时依赖的数据保存在内部存储 
若软件将配置文件存储在SD卡上,然后在运行期间读取配置文件,根据其中数据进行工作,攻击者编写的软件可以修改这些配置文件,从而控制软件的运行。

对于此类配置文件,更为安全的方法是保存到内部存储;如果必须存储到SD卡,则应在每次使用前判断它是否被篡改,如与保存在内部的文件哈希值进行匹配。

3) 将软件安装包或者二进制代码保存在内部存储或使用前进行校验 
部分软件会推荐用户下载并安装其他软件:用户点击后,会下载另一个软件的apk,保存到SD卡然后安装。有一些软件为了实现功能扩展,选择动态加载并执行二进制代码。如果在安装或加载前,该部分数据被篡改或伪造,就会出现安全问题。攻击者可以使用“重打包”(re-packaging)方法加入恶意代码、改变软件的数据或指令,而软件原有功能和界面基本不会受到影响,用户难以察觉。

为了

以上是关于Android程序猿必看之《终端应用开发指南》的主要内容,如果未能解决你的问题,请参考以下文章

多线程必看之JAVA线程并发辅助类

计算机网络必看之·你确定了解应用层吗?(下)

第四话·数据结构必看之·单链表就这?

第五话·数据结构必看之·栈 真的这么简单?

零基础必看之数学建模索引

计算机网络必看之·你确定了解传输层吗?