app研发录第一章笔记

作者: 大前端圈 | 来源:发表于2016-08-26 10:26 被阅读127次

    笔记提纲

    app研发录第一章.png

    1.1,重新规划 Android 项目结构

    第一步:建立 AndroidLib 类库,将与业务无关的逻辑转移到 AndroidLib。
    • 1, activity 包中存放的是与业务无关的 Activity 基类。Activity 基类要分两层。
      AndroidLib 下的基类 BaseActivity 封装的是业务无关的公用逻辑,主项目中的 AppBaseActivity 基类封装的是业务相关的公用逻辑。
    • 2, net 包里面存放的是网络底层封装。这里封装的是 AsyncTask。
    • 3, cache 包里面存放的是缓存数据和图片的相关处理。
    • 4, ui 包中存放的是自定义控件。
    • 5, utils 包中存放的是各种与业务无关的公用方法,比如对 SharedPreferences 的封装。
    第二步:将主项目中的类分门别类地进行划分,放置在各种包中。

    各个包的介绍如下:

    • 1,activity:我们按照模块继续拆分,将不同模块的 Activity 划分到不同的包下。
    • 2,adapter:所有适配器都放在一起。
    • 3,entity:将所有的实体都放在一起。
    • 4,db:SQLLite 相关逻辑的封装。
    • 5,engine:将业务相关的类都放在一起。
    • 6,ui:将自定义控件都放在这个包中。
    • 7,utils:将所有的公用方法都放在这里。
    • 8,interfaces:真正意义上的接口,命名以 I 作为开头。
    • 9,listener:基于 Listener 的接口,命名以 On 作为开头。

    这些划分主要是为了以下两个目的
    1)每个文件只有一个单独的类,不要有嵌套类,比如在 Activity 中嵌套 Adapter、Entity。
    2)将 Activity 按照模块拆分归类后,可以迅速定位具体的一个页面。此外,将开发人员按照模块划分后,每个开发人员都只负责自己的那个包,开发边界线很清晰。

    1.2 为 Activity 定义新的生命周期

    把onCreate()方法拆分为几个方法:

    • initVariables()
    • initViews()
    • loadData()
      1,initVariables :初始化变量,包括 Intent 带的数据和 Activity 内的变量。
      2,initViews:加载 layout 布局文件,初始化控件,为控件挂上事件方法。
      3,loadData:调用 MobileAPI 获取数据。

    这三个方法都是抽象的,所有子类都必须实现这三个方法,这样避免了onCreate方法过于臃肿,做的东西过多,也是单一职责的体现,一个类或方法,只做一件事情。

    1.3 统一事件编程模型

    给按钮点击事件增加方法,只要在一个团队内部达成了协议,决定使用某种事件编程方式,所有开发人员就要按照同样的方式编写代码。

    1.4 实体化编程

    1.4.1 在网络请求中使用实体

    要知道 JSONObject 和 JSONArray 都是不支持序列化的,所以只好将这种对象封装到一个全局变量中,在跳转前设置,在跳转后取出,这是一种很糟糕的写法。
    有以下两个问题:
    1)根据 key 值取 value,我们可以认为这是一个字典。同样的功能实现,字典比实体更晦涩难懂,容易产生 bug。
    2)每次都要手动从 JSONObject 或者 JSONArray中取值,很烦琐。
    建议把网络请求返回的 JSON 数据,通过fastJSON 或者 GSON 解析成javaBean实体。

    1.4.2 实体生成器

    作者自己写了一个程序,根据json字符串自动产生javabean
    在android studio中,可以使用GsonFormat插件将json数据转化为实体bean

    1.4.3 在页面跳转中使用实体

    很多人在页面跳转传递参数时,设置一个全局变量,在来源页设置全局变量,在目标页接收全局变量。
    这是一个很不好的做法,App一旦被切换到后台,当手机内存不足的时候,就会回收这些全局变量,从而当App再次切换回到前台时,再继续使用全局变量,
    就会因为他们为空而崩溃。

    如果必须使用全局变量,就一定要把它们序列化到本地。这样即使全局变量为空,也能从本地文件中恢复。

    建议使用 Intent 在页面间来传递数据实体bean,不过这个实体bean一般需要实现Serializable接口,以支持序列化。

    1.5 Adapter 模板

    统一规范,要求所有的 Adapter 都继承自 BaseAdapter,从构造函数注入 List< 自定义实体 >这样的数据集合,从而完成 ListView 的填充工作。

    如果不对 Adapter 的写法进行规范,开发人员还是会根据自己的习惯,写出来各种各样的 Adapter,比如:
    � � 1,很多开发人员都喜欢将 Adapter 内嵌在 Activity 中,一般会使用 SimpleAdapter。
    � � 2,由于没有使用实体,所以一般会把一个字典作为构造函数的参数注入到 Adapter 中。
    建议:这些写法都会看起来代码不统一,不便于其他人的修改。 Adapter 只有一种编码风格,这样发现了问题也很容易排查。

    1.6 类型安全转换函数

    类型转换不正确导致的崩溃占了很大的比例。发现主要集中在两个地方:Object 类型的对象、substring 函数。

    1)对于一个 Object 类型的对象,我们对其直接使用字符串操作函数 toString,当其为null 时就会崩溃。
    比如,我们经常会写出下面这样的程序:
    int result = Integer.valueOf(obj.toString());
    一旦 obj 这个对象为空,那么上面这行代码会直接崩溃。
    这里的 obj,一般是从 JSON 数据中取出来的,对于 MobileAPI 返回的 JSON 数据,我们无法保证其永远不为空。

    比较好的做法是,我们需要编写一个类型安全转换函数 convertToInt,实现如下,其核心思想就是,如果转换失败,就返回默认值:

          public f inal static int convertToInt(Object value, int defaultValue) {
              if (value == null || "".equals(value.toString().trim())) {
                  return defaultValue;
              }
              try {
                  return Integer.valueOf(value.toString());
              } catch (Exception e) {
              try {
                    return Double.valueOf(value.toString()).intValue();
              } catch (Exception e1) {
                    return defaultValue;
              }
              }
        }
    

    2)如果长度不够,那么执行 substring 函数时,就会崩溃。

    Java 的 substring 函数有 2 个参数:start 和 end。
    对于第一个参数 start,我们的程序大多是设为 0,所以一般不会有问题。但是要设置为大于 0 的值时,就要仔细思量了,比如:
    String cityName = "T";
    String f irstLetter = cityName.substring(1, 2);
    这样的代码必然崩溃,所以每次在使用 substring 函数的时候,都要判断 start 和 end 两个参数是否越界了。应该这样写:

              String cityName = "T";
              String f irstLetter = "";
              if (cityName.length() > 1) {
                  firstLetter = cityName.substring(1, 2);
              }
    

    以上两类问题的根源,都来自 MobileAPI 返回的数据,由此而引出另一个很严肃的问
    题,对于从 MobileAPI 返回的数据,可信度到底有多高呢?
    首先,不能让 App 直接崩溃,应该在解析 JSON 数据的外面包一层 try…catch…语句,
    将截获到的异常在 catch 中进行处理,比如说,发送错误日志给服务器

    总结:
    1,AndroidLib 这个业务无关的类库,我们将在接下来的章节中封装更多的公用逻辑
    2,实体化编程将极大提升代码可读性
    3,为 Activity 定义新的生命周期,也是提升代码可读性的一个手段。

    相关文章

      网友评论

        本文标题:app研发录第一章笔记

        本文链接:https://www.haomeiwen.com/subject/qtzasttx.html