17.《APP研发录》笔记

一、重构,夜未眠
1.重新规划Android项目结构
第一步,建立AndroidLib类库,将与业务无关的逻辑转移到AndroidLib。activity(无业务无关的Activity基类)、net(网络底层封装)、cache(缓存数据和图片的相关处理)、ui(自定义控件)、utils(与业务无关的公用方法,比如对SharedPreferences的封装)
第二步,将主项目中的类分门别类地进行划分,放置在各种包中。activity(将不同模块的Activity划分到不同的包下)、adapter(所有适配器放在一起)、entity(所有的实体都放在一起)、db(SQLite相关逻辑的封装)、engine(业务相关的类)、ui(自定义控件)、utils(公用方法)、interfaces(真正意义上的接口,命名以I作为开头)、listener(基于Listener的接口,命名以On作为开头)
2.为Activity定义新的生命周期
拆分成子方法
3.统一事件编程模型
点击方法用匿名内部类实现
4.实体化编程
JSON用GSON等第三方类解析,使用fastJSON时混淆文件要添加:--keepattributes Signature,--keepattributes Annotation
实体生成器:EntityGenerater
页面跳转中使用实体时不建议使用全局变量,可能被回收然后App崩溃。可把实体实现Serializable然后传送。
5.Adapter模板
所有Adapter都继承自BaseAdapter,从构造函数注入List<>这样的数据集合。
6.类型安全转换函数
对于一个Object类型的对象,我们对其直接使用字符串操作函数toString,当其为null时就会崩溃,所以实现一个判断是否为空的转换函数。
如果长度不够,那么招行substring函数时,就会崩溃。所以在使用时要判断start和end两个参数是否越界了。

二、Android网络底层框架设计
1.网络低层封装
不推荐使用AsyncTask来封装网络底层,因为可扩展性不高。
现在一般使用RxJava+Retrofit
实例:使用原生的ThreadPoolExecutor+Runnable+Handler
2.App数据缓存设计
减少调用次数,然后把获取的数据保存在App上。
3.MockService
当API没做好时,自己模拟相关的的接口实现
4.用户登录
登录成功后场景:点击登录按钮,进入登录页面LoginActivity,登录成功后,直接进入个人中心,这种情况一路执行startActivity()就能达到目的;在页面A,想跳转到页面B,并携带一些参数,却发现没有登录,于是先跳转到登录页,登录成功后,再跳转到B页面,同时仍然带着那些参数,用setResult实现;在页面A,执行某个操作,却发现没有登录,于是跳转到登录面,登录成功后再回到页面A,继续执行该操作,也是用setResult来完成回调。
自动登录,不推荐本地保存用户名和密码,使用Cookie机制,也叫Token。登录成功后,会从服务器获取到一个Cookie,取出来放在本地文件中即可。当用户注销时,要清空本地的Cookie。
Cookie过期统一处理:加一个onCookieExpired回调方法。
防止黑客刷库:登录接口增加第三个参数,比如验证码;同一IP短时间内频繁访问时要求输入验证码,用WebView实现。
5.HTTP头中的奥妙
请求、时间校准、开启gzip压缩

三、Android经典场景设计
1.App图片缓存设计
ImageLoader设计原理:在显示图片时,先在内存中查找;如果没有,就去本地查找;如果还没有,就开一个新线程去下载这张图片,下载成功会把图片同时缓存到内存和本地。对图片是软引用形式,所有内存中图片会在内存不足的时候被系统回收。
Freso原理:设计了一个Image Pipeline的要信,它负责先后检查内存、磁盘文件,如果都没有就去从网络下载图片。三层缓存:Bitmap缓存、内存缓存、磁盘缓存。
2.对网络流量进行优化
通信层面的优化:返回的数据存在于1KB时用gzip压缩;数据传递遵守JSON协议,推荐ProtoBuffer协议;减少网络访问次数;使用TCP长连接;建立取消网络请求机制,当一个页面没有请求完数据,跳转到另一个页面之前,把之前的网络请求都取消;增加重试机制。
图片策略优化:确保下载的每张图,都符合ImageView控件的大小;低流量模式,降低图片质量;极速模式,没有图片,只有文字。
3.城市列表的设计
4.App与HTML5的交互
用PhoneGap太重,把交互操作在底层封装,然后给开发人员使用。
对于经常需要改动的页面,做成H5页面,在App中以WebView的形式加载。H5开发周期短,但慢。可以做两套页面,Native一套,H5一套,在App中设置一个变量,判断该页面用哪个。变量从后台中获取。
5.消灭全局变量
在内存不足时,系统会回收全局变量,会导致APP崩溃。解决这个问题,使用序列化技术。
对社交和电商类App而言,页面繁多,没必要保存页面状态,直接让页面重新执行一遍onCreate方法,丢失的数据让用户重新操作。使用MVVM设计模式,可以把ViewModel序列化到本地,用以保存页面。
SharedPreferences中存放的变量数量应严格控制。
User是唯一例外的全局变量:序列化到本地,避免崩溃

四、Android命名规划和编码规范
1.Android命名规范
Activity、Adapter、Entity都为结尾,控件缩写,常量命名等

2.Android编码规范
分门另类存放各种类,Layout中使用的常量定义在Strings.xml中,Layout控件字体大小,定义在dimens.xml中,拆分onCreate,JSON解析用第三方库,页面传值用Intent,控件事件用匿名内部类,Activity中不要嵌套内部类,实体不要在不同模块间共享,节省内存,使用ArrayList而不是HashMap,图片处理用第三方,尽量使用ApplicationContext代替Context,数据类型转换一定要校验,使用常量代替枚举。

3.统一代码格式
团队中所有人使用同一种代码格式

五、Crash异常收集与统计
1.异常收集
设计一个CrashHandler类,继承自UncaughtExceptionHandler,处理未捕获的异常。基本关键方法就handleException,做三件事:发错误日志到服务器,给用户崩溃前的友好提示,把错误日志记录到SD卡。

2.异常收集与统计
要么记录到第三方平台,要么记录到自己的数据库中然后处理

六、Crash异常分析
1.Java语法相关的异常
空指针NullPointException、角标越界IndexOutOfBoundsException/StringIndexOutOfBoundsException/ArrayIndexOutOfBoundsException、试图调用一个空对象的方法、类型转换异常、数字转换错误,声明数组长度为-1、遍历集合同时删除其中元素、比较器使用不当、当除数为0、不能随便使用的asList、又有类找不到了(一):ClassNotFoundException、又有类找不到了(二):NoClassDefFoundError

2.Activity相关的异常
找不到Activity、不能实例化Activity、找不到Service、不能启动BroadcastReceiver、startActivityForResult不能回传、猴急的Fragment

3.序列化相关的异常
实体对象不支持序列化、序列化时未指定ClassLoader、反序列化时发现类找不到:被ProGuard混淆导致的崩溃、反序列化时发现类找不到:传入畸形数据、反序列化时出错

4.列表相关的异常
Adapter数据源变化但是没通知ListView、ListView滚动时点击刷新按钮后崩溃、AbsListView的obtainView返回空指针、Adapter数据源变化但是没调用notifyDataSetChanged

5.窗体相关的异常
窗口句柄泄露、View not attached to window manager、窗体在不恰当 的时候获取了焦点、token null is not for an application、permission denied for this window type、is your activity running、添加窗体失败、AlertDialog.resolveDialogTheme、The specified child already has a parent、子线程不能修改UI、不能在子线程操作AlertDialog和Toast

6.资源相关的异常
Resources$NotFoundException、StackOverFlowError、UnsatisfiedLinkError、InfiateException之FileNotFoundException、InfiateException之缺少构造器、InfiateException之style与android:textStyle的区别、TransactionTooLargeException

7.系统碎片化相关的异常
NoSuchMethodError、RemoteViews、pointerIndex out of range、SecurityException之一:Intent中图片太大、SecurityException之二:动态加载其他apk的activity、之三:No permission to modify thread、view的getDrawingCache()返回null、DeadObjectException、Android 2.1 不支持SSL、ViewFlipper引发的血案、ActivityNotFundException、Android 2.2 不支持xlargeScreens、Package manager has died、SpannableString与富文本字符串、Can not perform this action agter onSaveInstanceState、Service Intent must be explicit

8.SQLite相关的异常
No transaction is active、忘记关闭Cursor、数据库被锁定、试图再打开已经关闭的对象、文件加密了或无数据库、WebView中SQLLite缓存导致的崩溃、磁盘读写错误、android_metadate表不存在、android_metadata表中locale字段、数据库或磁盘满了

9.不明觉厉的异常
内存溢出、Verify Failed

10.其他情况的异常
TimeoutException、JSON解析异常、JSONArray在初始化时为空、第三方SDK抛出的Crash、两个不同类型的View有相同的id、LayoutInflater.from().inflate()使用不当导致的崩溃、ViewGroup中的玄机、Monkey点击过快导致的崩溃、图片宽高为0、不能重复添加组件

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,057评论 25 707
  • 整个高中似乎都是吊儿郎当的过来的,所以高考的成绩可想而知。高考考下来,分不够上二本,读了个预科。 到了大学才知道,...
    023木木木阅读 464评论 0 0
  • 水晶的灯光 美丽的华裳 你一个人孤独的等着散场 风里听见了谁的歌唱 ……
    南国雪阅读 333评论 3 0