Android项目规范

来源:互联网 发布:mac ftp 看不到文件夹 编辑:程序博客网 时间:2024/06/05 09:42

在开发一个Android项目之前,我们需要对团队的编程风格进行一个规范。而不是百花齐放,这样有利于项目的重构和纠错。

分模块

将项目中分为业务逻辑相关和业务逻辑不相关两部分,建立AndroidLib类库,把业务逻辑无关的工作放到AndroidLib中去,业务相关的逻辑放到主项目。类似于我们使用okHttp库去进行网络请求,然后主要的业务逻辑却会在主项目进行处理。主项目依赖AndroidLib库。

分包
AndroidLib应该包含以下几个部分:

  1. activity 业务无关的Activity基类,BaseActivity(业务无关的公用逻辑)。
  2. net 网络底层封装。
  3. cache 缓存数据和图片的相关处理。
  4. ui 自定义控件。
  5. utils 业务无关的公用方法。

主项目

  1. activity 创建业务相关的AppBaseActivity,在这个基础上进行各个模块的继续拆分,将不同模块的Activity划分到不同的包下。
  2. adapter 所有的适配器都放在一起。
  3. entity 所用的实体类。
  4. db SQLLite相关逻辑。
  5. engine 业务相关的类。
  6. ui 自定义控件。
  7. utils 所用的公共方法。
  8. interfaces 正真意义上的接口,命名以I开头。
  9. listener 基于Listener的接口,命名一On开头。

注意:Entity应该只有属性,否则不叫Entity。只有在Entity有上百个类的时候才进行模块划分。

创建BaseActivity
如果我们在Activity得 onCreate方法中放置太多内容,就会增加阅读难度。如下:

public class Main2Activity extends AppCompatActivity {    private ListView listView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        listView = (ListView) findViewById(R.id.listView1);        String[] adapterData = new String[]{"Afghanistan", "Albania", "Bosnia"};        listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, adapterData));        setListViewHeightBasedOnChildren(listView);    }}

显然这样做不符合SOLID原则,所以我们会考虑将他们提取到格子方法中去,而不是让onCreate去负责所有的事情。上述部分主要有三个方面的逻辑:变量的初始化、控件的初始化、数据加载。所以可以将这三个部分的逻辑分别提取到对应的方法中去,这样于都起来会变得比较直观。
代码如下

public class BaseActivity extends AppCompatActivity {    private ListView listView;    String[] adapterData;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        initVariables();        initViews();        loadData();    }    //变量的初始化    public void initVariables() {        adapterData = new String[]{};    }    //控件的初始化    public void initViews() {        listView = (ListView) findViewById(R.id.listView1);        listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, adapterData));    }    //数据加载    public void loadData() {        adapterData = new String[]{"Afghanistan", "Albania", "Bosnia"};    }}

统一事件编程模型
我们开发中一般在写控件的点击事件的时候,都使用过一下两种方式。

  • 第一种方式
public class ScrollActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_scroll);    findViewById(R.id.myView).setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                Toast.makeText(ScrollActivity.this,"click",Toast.LENGTH_LONG).show();                return true;            }        });    }}
  • 第二种方式
public class ScrollActivity extends AppCompatActivity implements View.OnTouchListener {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_scroll);     findViewById(R.id.myView).setOnTouchListener(this);    }    @Override    public boolean onTouch(View v, MotionEvent event) {        switch (v.getId()) {            case R.id.myView:                Toast.makeText(ScrollActivity.this, "click", Toast.LENGTH_LONG).show();                break;        }        return false;    }}

其实这两种方式没有明显的区别,只是使用第一种方式看起来会更加明了,符合面向对象编程的风格。

实体化编程
在解析网络数据的时候尽量使用Gson或者fastJson这样的实体化编程。这样可以方便对象的传递,前提是需要实现序列化,而不要使用全局变量进行传递,因为垃圾回收时候可能会将全局变量回收,这样就得不到原来的值。如果的确需要这样使用,可以考虑使用数据持久化,将变量的值保存到本地,这样即使被回收也可以从本地读取回来,而不至于出先奇怪的现象。

参考书籍

  • 《App研发录》
1 0
原创粉丝点击