《App研发录》知识点汇总

原文链接:http://www.jianshu.com/p/fc8c4638937e

  《App研发录》这部书是包建强写的,说来也巧,在读这边书之前在看池建强的《Mac 人生元编程》 ,所以读这本书的时候,将这两个建强搞混。这本书花了我一周多一点的时间看完。昨天晚看完久久不能寐,一是惊叹这本书的干货太多,这本书不同于市面上其他的Android 教程,给你讲一堆API方法,Android 基础,作者从一个APP团队的负责人的角度高屋建瓴的讲解App框架设计,Bug收集汇总分析,团队建设,项目管理等等方面,而且都是非常适合APP的项目管理者的实在的经验。二是敬佩作者进入Android 领域也不是很久,但是见解非凡,经验老道,感到自己做Android 也快两年了,为啥还达到没有作者的一半高度。唉,看来自己之前的两年过得太轻松了,每天混混日子,自以为懂些Android 技术,能实现产品交代的功能,就得过且过,没有好好的利用好时间,认真学习,加速成长。

  题外话太多了,自己觉得有些东西是多余的,是自己的无病呻吟,各位看官,可以忽略不看,直接看下面的干货。


一、APP 框架

1. 项目结构

  非常赞同作者的观点,我们App必须具有良好的包结构,按照一定规则将不同的类放到不同的地方,目前市面上有两者结构,一种是按照类的类型进行归纳放置,例如Activity 类放一起,adapter 放一起,以此类推;另外一种是按照业务逻辑,例如主页页面逻辑放在一个小包中,用户信息逻辑放在一个小包中,当然小包中可以再分包。
两种都可以,但必须具有一致项目结构,不要弄得不三不四,类到处放,没有一定规则

2. baseActivity、BaseAdapter基类管理

3. 网络框架,封装好网络层。

  • 不要使用AsyTask,因为他在4.x 版本中是串行,效率不高,而且当请求线程数达到AsyTask上线时会有问题。建议用TheadPoolExecutor+Runnable+Handler 的方式进行封装。

4. 数据缓存策略:

  • 为减少请求网络数据次数,有必要进行数据缓存,将请求网络的数据,缓存在手机上,为保证数据即时性,设置缓存时间,而且可以根据业务需求对不同数据设置不同的缓存时间,有的数据不咋改变可以设置长些时间,有些数据经常变动,对即时性要求比较高,缓存时间设置短些,设置可以不设置缓存。
  • 另外必须有接口能够让用户强制更新数据,例如用户下来刷新,就不要使用缓存中数据,而是直接请求最新的网络数据

5. 用户登录

  • 考虑用户登录各种场景

    • 一种用户开始登录然后进入主页面,
    • 二种用户没有登录数据不能进入下一界面,需要跳转登录页,再跳回来,
    • 三种用户请求网路但是用户身份验证失败需要跳到登录注册页。
    • 前面一种好说,后面两种可以设置回调进行处理,有种情况可能比较麻烦,例如用户进入某一页面没有用户信息,需要跳回登录注册页,可是登录注册完成后又得填资料补全身份信息等最后,经过一系列流程后才跳回原始的页面。

       1 //起始页面,可能需要跳转登录注册页
       2     if(User.isLogin()){
       3          //do something
       4         }else{
       5     Intent intent=new Intent(this,LoginActivity.class){
       6     intent.putExtra(AppConstant.NeedCallback,true);
       7     startActivityForResult(intent,LOGIN_REDIEECT_INSIDE);
       8         }
       9     }
      10
      11 @Override
      12 public void onActivityResult(int requestCode, int resultCode,Intent data){
      13     if(resultCode!=Activity.RESULT_OK){
      14         return;
      15       }
      16     swith(requestCode){
      17        case LOGIN_REDIEECT_INSIDE:
      18            //  do something
      19             break;
      20        default:
      21        break;
      22     }
      23 }
      24
      25 //登录页面 LoginActivity
      26 if(getIntent.getBooleanExtra(AppConstant.NeedCallback){
      27     setResult(Activity.RESULT_OK);
      28     finish();
      29 }ese{
      30    //do otherthing
      31 }
  • 用户信息存储风险

    • 用户的信息我们在app中多处用到,我们建议将他持久化处理,并且将其文件存储起来。要考虑我们用户信息失效问题。
    • 另外用户的密码必须经过加密处理,我建议客户端将用户输入的密码加密处理后才传给服务端,服务端对传过来的密码也进行一层加密,以保证用户安全。
    • 另外我不建议存储用户的密码,即时是加密后的密码,可以使用Token机制(有的也叫Cookie机制),储存Token,这个Token可以当成用户身份的唯一性标识。用户客户端登陆后,服务器生成Token,当用户调用与用户信息相关的接口时,将用户ID 与Token 传给服务器,服务器首先根据Token与ID验证用户正确性,然后才将数据传给用户
  • 自动登陆功能
    • 自动登陆功能需要储存用户的密码,需要注意密码的安全性问题。而且自动登陆与输验证码相斥问题。
  • 使用Cookie方法保证用户信息安全
    • 当用户登录成功后,从后台获取到Cookie,Cookie在Http-Respose的头文件中,我们将他取出来,下次联网请求数据时将Cookie放入Http-Request的头文件中,如果请求数据与用户信息相关,服务器验证身份成功才返回数据。
    • 每次请求后客户端必须更新Cookie。
    • 另外注意Cookie过期问题,及用户注销后,需要将用户信息清空。

6. 防止黑客刷库

  • 第一种方法,登录时添加验证码
  • 第二种方法,登录三次失败后才需要用户输入验证码
  • 第三种方法,后台检测某一IP在短时间内频繁访问登录接口,然后用户输入验证码。

7. 时间校准问题

  • 如果后台或者用户端对时间准确性要求比较高的话,需要考虑这个问题。因为我们用户手机上的时间不是非常准确,一般都有一定的偏差。作者建议后台采用UTC时间,包括入参和返回值,返回值为long类型。客户端根据得到的UTC时间换算成本地时间。如果需要用户传给后台准确的时间,这是个大问题。用户那边其实很难得到比较准确的时间,除了用户时区问题,另外还有与准确时间偏差问题。可以用户的时间传给后台,后台比对差值,然后每次不停的比对减少误差,最后找到一个准确值。

8. gzip 压缩

  • 一般http采用gzip压缩,减少传输量,缩短传输时间。但是在HttpRespose 需要判断content-encoding字段中是否有gzip,判断后台是否经过gzip压缩。

9. Freso的三级缓存

  • 第一层:Bitmap 缓存

    • 在Android 5.0中,考虑内存管理有了很大的进步,所以讲Bitmap 缓存在Java堆中,在之前版本中Bitmap缓存在ashmen中,当app切换到后台时,Bitmap缓存将会被清空
  • 第二层:内存缓存
    • 内层缓存中存储了图片原始压缩的格式,从内层缓存中取出图片,在显示之前必须进行解码。当app切换到后台,内存缓存也被清空
  • 第三层:磁盘缓存,也叫本地缓存
    • 本地存储图片原始压缩格式,显示之前也需先解码,当app切换后台,磁盘缓存不会丢失。

10. 流量优化

  • 数据压缩(常见gzip)
  • 使用更好的数据传递协议。例如比JSON更好的ProtoBuffer
  • 合并api,防止客户端频繁调用api请求
  • http无状态短连接改成TCP长连接。但是需要对服务器及后台有要求
  • 页面销毁需要取消之前的网络请求
  • 增加重试机制,例如get请求失败重试三次,但是需要防止用户重复下单,重复发布评论,重复付款等,
  • 图片请求附带尺寸参数,服务端更加尺寸传输最近尺寸的图片。
  • 低流量模式,降低图片质量或尺寸,甚至可以不返回图片的极速模式

11.增量更新

  • app中的资料包,城市列表等素材可以使用增量更新。每次发版素材保证是最新的版本,当有更新时,首先对比本地素材版本号与线上素材版本号,后台根据他们版本号返回对应的更新内容。客户端收到后解压。
  • 增量更新的内容有三部分:需要删除的数据、不变的数据但是需要修改、新增的数据,用户根据情况各自处理

12. Html 互换技术

  • 当我们的app原生页面遇到bug,可以马上切换到Html页面替换。

二、Crash及持续集成

1. Crash 的收集

  • 收集的渠道

    • 集成第三方统计工具。友盟、leadCould
    • 集成Bug管理工具,例如Bugly,BugTag等
    • app本地收集,将错误日志记录在本地,然后发送到后台服务器,另外需要标注Crash时间,Crash名称,详细信息,手机版本,设备号,渠道号,当前网络类型,内存使用情况等等。
      本地bug收集需要用到UncaughtExceptionHandler这个类

2.Crash经验

  1. 窗体泄露问题,主要是想关闭弹出框时,他所承载的activity 不在了,而activity关闭了,没有及时dismiss会导致泄露窗口句柄,不要在子线程操作对话框,另外让对话框是Activity成员变量,活跃在onCreate()和onDestroy()两个方法之间,或者建议使用DialogFragment。
  2. 只有activity 才能添加窗体,传给Dialog的Context 要为activity。
  3. 不要相信api 返回数据,必须做非空判断,类型异常等容错处理
  4. 遍历集合时不能删除集合中数据,否则发生崩溃。另外多个线程同时操作同一集合数据也可能会发生崩溃
  5. 当Service或者BroadcastReceiver等中当context 为非activity 跳转activity需要加Intent.FLAG_ACITIVITY_NEW_TASK
  6. 当fragment还没有attach 到activity中调用getResource().getString()会报错,建议在调用之前加上isAdd()判断
  7. Parcelable 反序列化时,例如a=in.readParcelable(null)会可能抛出BadParcelabeException:ClassNotFoundException when unmarshalling...改成这样就行a=in.readParcelable(A.class.getClassLoader)
  8. List<T> 没有实现add()、remove()方法, 使用这两个方法会抛异常,特别注意Arrays.asLis() 返回的是List<T>,而不是ArrayList();
  9. 只要修改了adapter中的集合的数据,就要马上调用notifyDataSetChanged方法,以保证列表同步更新,否则崩溃。
  10. ListView滚动式点击刷新按钮后会崩溃,因为之前getCount还有数据,滚动时刷新数据集合就清掉了,getView 中数据为空,报数据越界等异常,一般解决方案是,滚动时,禁止刷新。
  11. PopupWindow创建后才能再调用setFocusable() 方法。
  12. PopupWindow.showLocation(view parent,int gravity,in x,int y),当参数parent 为空时,报Unable to add Windowtoken,因为popupWindow要依附activity,activity还没有onCreate()执行完,就会报此错误。
  13. armeabi 和armeabi-v7a中so包数量不一致,会导致UnsatisfiedLinkError。
  14. SQLite 支持单线程、多线程、串行三种模式。但是多线程中使用单个数据库连接不是安全的,当一个线程写数据,一个在删数据会抛I/O 异常,当一个操作完关闭数据库,另外一个还在操作也会导致Crash。
  15. <application android:largeHeap="true"可以增加系统为当前app 分配内存,甚至能到达100M以上,但是每次GC 时间会延长,性能会下降。
  16. WebView中存在两种缓存:网页数据缓存,存储打开过的页面及资源;Html5缓存,及appCache。WebView自带的缓存机制,会将url保存在webviewCashe.db中,将url内容保存在webViewCashe文件夹下,网页数据图片、html、js等文件也会存储起来

三、ProGuard

ProGuard一共包含以下4个功能:

  • 压缩(Shrink):侦探并移除代码中无用的类、字段、方法和特性(Attribute)。
  • 优化(Optimize):对字节码进行优化,移除无用的指令
  • 混淆(Obfuscate):使用a、b、c、d这样无意义名称,对类、字段和方法进行重命名
  • 预检(Preverify):在Java平台上对处理后的代码进行预检。

四、竞品分析

1. 竞品app分析方向(针对技术):

  • 为啥他们的App体积比我们小
  • 为啥他们App访问速度比我们快
  • 为啥他们App基本上不咋崩溃
  • 等等···

2. 优化措施

  • Splash 广告提速:首次加载App包中图片,同事调用API获取下一次打开图片的Url,并存储本地,下次Splash就加载下载下来的新图片,并调用API查看是否有新 的Splash图片要下载。
  • HTML5页面提速:将常用的HTMl5打成Zip包,每次启动时,启动异步线程,将zip包解压到本地,每次从本地读取Html5页面,就不用从服务器加载Html 页面。为保证Html5为最新的,每次加载html5页面之前,可以询问服务器html的版本号,如果过期重新下载最新zip包。
  • zip包采用增量更新机制:每次发版前将最新的Zip包放在App安装包中。客户端下载Zip只需包括新增的和修改的就行,另外控制增量包在100KB之内。
  • png/jpg使用:手机会对png图片进行硬件加速,同样图片png体积比jpg大,但是加载速度要快些。app图片优先使用png格式。但是大尺寸图片,为减少apk 包体积可使用jpg。考虑流量及下载速度需网络下载的图片使用jpg。
  • 使用webP,vetorDrawable、ttf 等
  • 自动选取最佳服务器策略:全国各地多台服务器,并分别接入电信、移动或者联通专线,让app尝试从哪个服务器连接速度快些
  • TCP+ProtoBuf:已有公司抛弃短连接Http+json,开始走TCP+ProtoBuf路线。但是需要保证服务器的性能压力,考虑网络状况情况。
  • Native 页面和Html 页面相互替换。当原生页面崩溃掉,使用html页面顶上。
时间: 2024-10-13 20:11:46

《App研发录》知识点汇总的相关文章

APP研发录

APP研发录 1.代码重构 2.网络框架 3.场景设计 4.编码规范 5.异常管理 6.代码混淆 7.持续集成 8.竞品技术 9.项目管理 10.日常问题 11.无线团队 来自为知笔记(Wiz)

《App研发录》面世

古者富贵而名灭,不可胜记,唯倜傥非常之人称焉.故西伯拘而演<周易>,屈原放逐,乃赋<离骚>.文人雅士一次次的谱写着千古绝唱,而我亦不能免俗,也要附庸风雅,写一部前不见古人.后不见来者的经典之作. 于是,历时一年,呕心沥血,结合自身3年来从事App领域的一线实战经验,再辅之以从事软件行业十余载的奇技淫巧,写下这洋洋洒洒三百多页十几万字.初稿完成后,就如同和氏璧般,竟找不到出版社愿意出版,而我又不肯妥协,去写那些无关痛痒的语法介绍和UI布局等入门级章节.就在这时,杜勇帮我介绍了机械工业

APP研发录笔记

一.消灭全局变量 在内存不足时,系统会回收一部分闲置的资源,由于App被切换到后台,所以之前存放的全局变量很容易被回收,这时再切换到前台继续使用,会报空指针崩溃.想彻底解决这个问题,就要使用序列化. 1.把数据作为intent的参数传递 使用intent进行页面间数据的传递,即使activity被摧毁,intent上的数据依然存在,所以intent是保存数据的好地方,比本地文件靠谱. 但是intent能传递的数据类型也必须支持序列化,像JSONObject这样的数据类型,是传不过去的. inte

vue2.0:(八)、外卖App弹窗部分知识点总结

本篇文章是对外卖App弹窗部分知识点的总结. 知识点一:如何从接口取出不同的图片. 答: 1.header.vue: 代码: <ul v-if="seller.supports" class="supports"> <li class="support-item" v-for="(item,index) in seller.supports"> <span class="icon&quo

Java研发工程师知识点总结

Java研发工程师知识点总结 最近一次更新2017年12月08日 大纲 一.Java基础(语言.集合框架.OOP.设计模式等) 二.Java高级(JavaEE.框架.服务器.工具等) 三.多线程和并发 四.Java虚拟机 五.数据库(Sql.MySQL.Redis等) 六.算法与数据结构 七.计算机网络 八.操作系统(OS基础.Linux等) 九.其他 一.Java基础(语言.集合框架.OOP.设计模式等) 1. HashMap和Hashtable的区别 Hashtable是基于陈旧的Dicti

赵雅智:js知识点汇总

赵雅智:js知识点汇总,布布扣,bubuko.com

CodeIgniter框架——知识点汇总

NO1.学习要点: 一.CodeIgniter 框架的简介 二.CodeIgniter 框架的安装 三.CodeIgniter 框架的目录结构分析 四.CodeIgniter 框架是如何工作的? 五.CodeIgniter 框架中的控制器.视图.模型及数据库操作 六.CodeIgniter 框架中辅助函数.类库.适配器的学习 七.…… NO2. 一.CodeIgniter 是什么? 1.CodeIgniter 是一个应用程序框架 CodeIgniter 是一个为用 PHP 编写网络应用程序的人员

《正则表达式》知识点汇总摘录

开园一个月了,但一直没有抽出多少时间,就算有时间,也不知道怎么组织语言记(不是写,是记,写是一个创造的过程,像我这等程序猿,猿嘴吐不出象牙!)点东西!翻翻过去手头整理的一些知识点杂记,然后再结合网上的一些,今天对正则表达式在做一个个人的知识汇总摘录吧!程序员都是共产主义者,一点不假!大部分时候我们只是互联网的搬运工,堆砌者(扯远了,当然成为互联网创造者一直使我们的目标!). 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个"规则字符串&quo

软考网络工程师易混淆的知识点汇总

网络工程师考试是全国计算机技术与软件水平考试的一项中级资格考试,通过考试的合格人员能根据应用部门的要求进行网络系统的规划.设计和网络设备的软硬件安装调试工作,能进行网络系统的运行.维护和管理,能高效.可靠.安全地管理网络资源,作为网络专业人员对系统开发进行技术支持和指导,具有工程师的实际工作能力和业务水平,能指导网络管理员从事网络系统的构建和管理工作.网络工程师考试是软考的一大热门,怎样才能顺利通过考试是广大考生都想知道的,下面希赛软考学院为您带来网络工程师备考锦囊之应战篇,专业老师整理的网络工