第1章 重构,夜未眠

此文在我的个人网站,我的简书,我的CSDN博客
同时发布,请多多关注!

前言

这是我在读《App研发录》所摘抄的笔记。需知更多详情,请阅读原著。

重新规划Android项目结构

  1. 建立AndroidLib类库,将与业务无关的逻辑转移到AndroidLib(应至少包括以下部分)。

    • activity包中存放的是与业务无关的activity基类。
    • net包里面存放的是网络底层封装。
    • cache包里面存放的是缓存数据和图片的相关处理。
    • ui包中存放的是自定义控件
    • utils包中存放的是各种与业务无关的公用方法。比如SharedPreferences的封装。
  2. 将主项目中的类分门别类地进行划分,放置在各个包中。

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

这样划分的目的:

  • 每个文件只有一个单独的类,不要有嵌套类
  • 将Activity按模块拆分归类后,可以迅速地定位具体的一个页面。

为Activity定义新的生命周期

如果不经处理,onCreate()方法既要接收参数,又要加载布局,还有获取数据等操作,根据单一职责的原则,我们应该把onCreate()方法拆分成三个子方法:

  • initVariables():初始化变量,包括Intent带的数据和Activity内的变量。
  • initViews():加载Layout布局文件,初始化控件,为控件设置事件监听。
  • loadData():获取后台数据。
public abstract class BaseActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        initVariables();
        initViews(savedInstanceState);
        loadData();
    }

    protected abstract void initVariables();

    protected abstract void initViews(Bundle savedInstanceState);

    protected abstract void loadData();
}
public class MainActivity extends BaseActivity {
    private static final String TAG = "MainActivity";
    private EditText et;
    private int time;

    @Override
    protected void initVariables() {
        time = 0;
    }

    @Override
    protected void initViews(Bundle savedInstanceState) {
        setContentView(R.layout.activity_main);

        et = (EditText) findViewById(R.id.et);
    }

    @Override
    protected void loadData() {
        loadUserData();
    }
}

统一事件编程模型

在这里,作者比较推荐用匿名类的方式为控件设置事件的监听,有以下两个优点:

  1. 直接在按钮对象上增加点击事件,是面向对象的写法。
  2. 将onClick方面的实现,封装成一个方法。

但是,只要一个团队内部达成了协议,决定使用某种事件编程方式,所有的开发人员就要按照同样的方式编写代码。只要不是各有各的编码风格就好。

实体化编程

  • 在网络请求中使用实体

在转换后台返回的JSON数据时手动取值这种方式是不可取的。因为根据key值取value,我们可以认为这是一个字典。同样的功能实现,字典比实体更晦涩难懂,容易产生bug。而且每次都要手动从JSONObject或者JSONArray中取值,很繁琐。

推荐使用fastJSON和GSON。

  • 实体生成器

自定地把JSON转换成相应的实体,例如AndroidStudio上JsonFormat插件。

  • 在页面跳转中使用实体

不建议使用全局变量。App一旦被切换到后台,当手机内存不足的时候,就会回收这些全局变量。

使用Intent在页面间来传递数据实体的机制。

Adapter模板

现在使用Adapter一般都是继承自BaseAdapter,使用ViewHolder机制。

类型安全转换函数

  1. 对于一个Object类型的对象,我们对其直接使用字符串操作函数toString,当其为null时就会崩溃。

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

数据要分级别对待:

  • 对于那些不需要加工就能直接展示的数据,我们是不担心的,因为即使为空,页面上也就是不显示而已,不会引起逻辑的问题。
  • 对于那些很重要的数据,比如涉及支付的金额不能为空的逻辑,这时候就应该弹出提示框提示用户当前服务不可用,并停止接下来的操作。

总结

这一章更多的内容是写代码的方法,不过看了过后,相比自己之前写过的代码,确实是学到不少东西的。毕竟代码的规范性真的很重要,一目了然,结构清晰。

你可能感兴趣的:(《App研发录》笔记)