前言
这是我在读《App研发录》所摘抄的笔记。需知更多详情,请阅读原著。
重新规划Android项目结构
建立AndroidLib类库,将与业务无关的逻辑转移到AndroidLib(应至少包括以下部分)。
- activity包中存放的是与业务无关的activity基类。
- net包里面存放的是网络底层封装。
- cache包里面存放的是缓存数据和图片的相关处理。
- ui包中存放的是自定义控件
- utils包中存放的是各种与业务无关的公用方法。比如SharedPreferences的封装。
将主项目中的类分门别类地进行划分,放置在各个包中。
- 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();
}
}
统一事件编程模型
在这里,作者比较推荐用匿名类的方式为控件设置事件的监听,有以下两个优点:
- 直接在按钮对象上增加点击事件,是面向对象的写法。
- 将onClick方面的实现,封装成一个方法。
但是,只要一个团队内部达成了协议,决定使用某种事件编程方式,所有的开发人员就要按照同样的方式编写代码。只要不是各有各的编码风格就好。
实体化编程
- 在网络请求中使用实体
在转换后台返回的JSON数据时手动取值这种方式是不可取的。因为根据key值取value,我们可以认为这是一个字典。同样的功能实现,字典比实体更晦涩难懂,容易产生bug。而且每次都要手动从JSONObject或者JSONArray中取值,很繁琐。
推荐使用fastJSON和GSON。
- 实体生成器
自定地把JSON转换成相应的实体,例如AndroidStudio上JsonFormat插件。
- 在页面跳转中使用实体
不建议使用全局变量。App一旦被切换到后台,当手机内存不足的时候,就会回收这些全局变量。
使用Intent在页面间来传递数据实体的机制。
Adapter模板
现在使用Adapter一般都是继承自BaseAdapter,使用ViewHolder机制。
类型安全转换函数
对于一个Object类型的对象,我们对其直接使用字符串操作函数toString,当其为null时就会崩溃。
如果长度不够,执行substring函数时,就会崩溃。
数据要分级别对待:
- 对于那些不需要加工就能直接展示的数据,我们是不担心的,因为即使为空,页面上也就是不显示而已,不会引起逻辑的问题。
- 对于那些很重要的数据,比如涉及支付的金额不能为空的逻辑,这时候就应该弹出提示框提示用户当前服务不可用,并停止接下来的操作。
总结
这一章更多的内容是写代码的方法,不过看了过后,相比自己之前写过的代码,确实是学到不少东西的。毕竟代码的规范性真的很重要,一目了然,结构清晰。