1 重构夜未眠
本章主要分为对Activity、Adapter进行了重构的调整。
对于重复的代码可以对其进行抽象封装,可以抽象到父类中,子类实例化时就不需要重复编写(当然如果产生新的需求可以对类进行复写)。
感悟:重构使得代码变得更加简明优美,有利于后期的维护和优化,也使得代码模块之间形成了高内聚、低耦合。
2 android网络层框架设计
对网络底层:由于AsyncTask不能灵活的控制其内部的线程池(没有暴露出取消请求的方法),容易产生请求积压,使得在网速不乐观的情况下不能及时作出响应。解决方法:使用原生的ThreadPoolExecutor+Runnable+Handler对底层进行封装。
对ProgressBar进行重构,所以定义在AppBaseActivity中。
2.2 App数据缓存的设计
减少对MobileAPI的调用次数,可以将一次性需要取出的数据定义在一个全新的接口中,减少App的缓存时间。此外将那些即时性低、不怎么改变的数据进行缓存。同时还要对需要及时更新的数据进行强制更新。
2.4 用户登陆
1>点击登录,进入LoginActivity,登录成功后,进入个人中心。
2>在页面A,要跳到页面B,并携带一些参数,发现没有登录就跳转到登录界面,登录成功后跳转B页面,并还携带着那些参数。
3>在页面A,执行某个操作,发现没登录,跳转到登录页,登录成功后再回到页面A,继续执行该操作。
自动登录:
最直接办法,本地保存用户密码。
由于本地保存容易被窃取,所以本地保存一定要加密,对称密码是不可靠的。包括使用Cookie机制(Cookie的过期处理)和防止黑客刷库(使用验证码、检测到同一IP重复访问要求使用验证码)。
2.5 HTTP头中的奥秘
2.5.3 开启gzip压缩
HTTP协议上的gzip编码是一种用来改进Web应用程序性能的技术,大量的Web站点常常使用gzip,压缩技术来减少传输量的大小,可以减少存储空间,在网络传输时能减少传输时间。
使用gzip的流程:1>在APP发起请求的时候在HTTPRequest头中,添 加支持支持gzip的key-value,这里的key是Accept-Encoding,value是gzip。
Headers.put(FrameConstants.ACCEPT_ENCODING,“gzip”);
3 Android经典场景设计
3.1 App图片缓存设计
ImageLoader:的目的是为了实现异步的网络图片加载、缓存及显示,支持多线程异步加载。
ImageLoader的工作原理是:在显示图片的时候,它会在内存中查找,如果还没有就开一个新的线程去下载这张图片,下载成功就会保存在内存和本地。基于这个原理每次退出页面时就会把内存中的缓存都清除,下次再从本地取出。
ImageLoader的使用:由三大部件组成。
1>ImageLoaderConfiguration对图片缓存进行总体配置,包括内存缓存的大小、本地缓存的大小和位置、日志、下载策略(FIFO还是LIFO)等等。
2>ImageLoader 我们一般使用displayImage来把URL对应的图片显示在ImageView上。
3>DisplayImageOptions 在每个页面需要显示图片的地方,控制如何显示的细节(下载时的状态、是否将缓存放在内存或者本地磁盘)。
3.1.3 ImageLoader优化
尽管ImageLoader很强大,但一直把图片缓存在内存中,会导致内存占有过高。虽然对图片引用是软引用,软引用在内存不够的时候会被GC,但我们应该减少GC次数,所以要经常手动清理ImageLoader中的缓存。
我们在AppBaseActivity中的onDestory方法中,执行ImageLoader的clearMemoryCache方法,以确保页面销毁时,把为了显示这个页面而增加的内存缓存清除。即使内存中没有了,根据ImageLoader的缓存策略,还是可以在本地磁盘找到。
public abstract class AppBaseActivity extends BaseActivity{
protected boolean needCallback;
protected ProgressDialog dlg;
public ImageLoader imageLoader = ImageLoader.getInstance();
protected voidonDestory(){
// 回收该页面缓存在内存的图片
imageLoader.clearMemoryCache();
super.onDestory();
}
}
3.1.4 图片加载利器Fresco
Fresco的使用:
在Application级别,对Fresco进行初始化
Fresco.initialize(getApplicationContext());
与ImageLoader不同,Fresco是基于控件级别,所以我们把程序中显示网络图片的ImageView都替换为SimpleDraweeView即可,并在ImageView所在的布局文件中添加fresco命名空间。
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/imgView"
android:layout_width="10dp"
android:layout_height="10dp"
fresc:placeholderImage="@drawable/placeholder" />
在Activity中为这个图片控件指定要显示的网络图片:
Uri uri = Uri.parse("http://www.bb.com/a.png");
draweeView.setImageURI(uri);
Fresco的三级缓存使得它比其他图片的SDK吃内存小:
第一层:Bitmap缓存
第二层:内存缓存
第三层:磁盘缓存
Fresco有3个线程池,其中3个线程用于网络下载图片,2个线程用于磁盘文件的读写,还有2个线程用于CPU相关操作,比如图片解码、转换。
3.2 对网络流量的优化
3.2.1 通信层面的优化
MobileAPI层面进行优化:
1)MobileAPI接口返回的数据,需要使用gzip进行压缩。
2)App与MobileAPI之间的数据传输通常是遵守JSON协议的。全新的数据传输协议,ProtoBuffer。
3)接下来解决频繁调用MobileAPI。
4)传统的MobileAPI使用的是HTTP无状态短连接。但我们可以使用TCP长连接,提高访问速度。
5)要建立取消网络请求的机制。一个页面如果没有请求完网络数据,在跳转到另一个界面前,要把之前的网络请求都取消。
6)增加重试机制。一般会把获取请求接口定义为get,而把操作数据的请求接口定义为post。
3.4 App与HTML5的交互
4 Android命名规范和编码规范
良好的代码风格会让任何人接收的时候,不会因为风格迥异而花费更多的时间。
1>Java类文件命名规范
Activity命名规范:以Activity作为后缀,PersonActivity.
Adapter命名规范:以Adapter作为后缀,PersonAdapter.
Entity命名规范:以Entity作为后缀,PersonEntity.
2>资源文件命名规范
Layout目录下的文件命名规范:
页面布局文件。以act_为前缀,以Activity所在的Package作为中缀,以Activity的名称作为后缀。 act_person_addcustomer.xml
ListView中的item布局文件。以item_作为固定前缀,列表项的名称为后缀。item_lvuserlist.xml
第三部分 项目管理和团队建设
10 项目管理决定了开发速度
项目管理中的三驾马车:产品经理(灵魂)、开发(主力)、测试(保证)。
Scrum Master 敏捷开发
App敏捷开发流程:
迭代周期:每个公司都有自己的迭代周期。4周
迭代开始前:
1.总结上从迭代的问题。
2.修复上次迭代来不及处理的bug。
3.代码重构,但是要在产品需求完成的情况下再用剩下的时间对代码进行优化、项目重构。重构一般放在迭代前期,这样就有充分的时间来发现重构带来的各种问题。
4.讨论新需求
11 日常工作中的问题解决
使用二分法查找错误提交点。