大一的时候我就遇到一个问题,那就是如何把一个非常大型View交互非常复杂的Activity分解成较小的模块。这个问题伴随了我一年的时间,如鲠在喉。一年来自己就有一些思考,后来又受了L君代码的启发,找到了一种自己的办法,勉强算是MVP的一种实现吧。

最近,看到很多人还不知道这种拆分的方式,所以趁机分享一下,如果你觉得对自己有用请顺手点赞 Star

我的方法,现在想想也蛮简单。囿于当前的代码量和见识,这种结构也不一定完美,如果你有更好地思路,我们可以讨论,我的邮箱是danxionglei@foxmail.com


目标

理想中的代码结构有这样几个要求。核心目标是把过大的Activity的功能拆分开,方便的切分模块。除此之外,最好还能够有三个基本点,第一代码整洁干净,平时要用的ButterKnife都得有。第二,足够简单,不要让我为了这套东西还要写很多多余的东西。第三,要方便模块间的交互,这个交互,也就是事件的传递不能太啰嗦。

下面的这几个部分,可以根据需要略过,直接跳到最后

ButterKnife

ButterKnife 是一个依赖注入的第三方库,由业界牛人JakeWharton开发。

主要功能是,简化findViewById的使用。只需要一行注解,就可以轻松地进行绑定。

1
2
3
4
5
6
7
8
9
10
class MainActivity extends Activity{

@bind(R.id.button)
Button mButton;

@Overrides
protected void onCreate(Bundle savedInstance){
ButterKnife.bind(this);
}
}

第三行即为注解,表示将要把在 xml 中声明的R.id.button的实例绑定在这个变量中。

第八行,表示在编译时,才会将原有的findViewById编织到你的apk中,这样代码就会干净许多。

View “injection” library for Android.

Controller

总之Controller的功能就是分离和解耦。把冗杂的大模块,分离成小模块。

这里需要一提的是,我用的方法并不是MVP。我嫌正统的MVP那种方式太过繁琐。Presenter有一个很大的作用是路由,也就是View和Model的传声筒,一个函数里就为了调用一下其他的函数,我觉得很没有必要。所以,一般来讲,在我确认View层就是最简单的Xml,不会出什么幺蛾子,我就不会专门抽离View层。而是以我自己的方式,进行解耦。
同样可以达到功能分划解耦的目的。

实现

前面说了,我没有将mvp这三层分的太开,而是将整体按照功能分为一个个单元,把这些单元分开。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class MainActivity extends Activity{

MainController mController;

@Overrides
protected void onCreate(Bundle savedInstance){
super.onCreate(savedInstance);
mController = new MainController();
}
}

class MainController{

@Bind(R.id.button)
Button mButton;

public MainController(Context context, View view){
super(context, view);
ButterKnife.bind(this, view);
init();
}

public void init(){
mButton.setOnClickListener(new View.OnClickListener{
@Override
public void onClick(View view) {
button.setText(getString(R.string.text));
}
}
}
}

这样就把逻辑从Activity中抽离了出来,再也不用怕代码多了。如果一个Controller不够的话,还可以Controller再下辖Controller,这样形成的一个树的模式,整个app就形成了一个逻辑清晰的功能树。

恩,就是这样了。