先呵呵一下碎屏保。
框架github地址:https://github.com/white-cat/ThinkAndroid,有兴趣的同学可以先下载了看看,代码太多,文章里只会贴很少的一部分。
终于有时间把这两天对这个框架的解读做一些总结了。框架很大,会持续更新的。
10-29更新。
上自己画的架构图:
一. 先看MVC命令控制的部分。
命令
1.TAICommand为所有命令的接口。
2.TABaseCommand实现了普通命令的基本功能,是一个抽象类。
3.TABaseCommand和TAIResponseListener直接是一个观察者模式,命令执行的时候会通知所有的观察者,最重要的观察者就是TAApplication。
Command中生成不同的Response,然后通过handler传递到TAAppliction来进行解析和执行。
命令队列处理模块
1.TACommandQueue是一个阻塞队列(LinkedBlockingQueue)
2.TAThreadPool管理1到多个(Demo是两个)TACommandThread。
3.TACommandThread是命令队列TACommandQueue的“消费者”,当队列中有“产品时”就取出来执行。
4.TACommandQueueManager封装了queue和threadPool,单例模式,对外提供queue和threadPool的初始化,以及入队,获取值,清队,以及关闭线程等功能。
5.TACommandExecutor封装TACommandQueueManager,同时通过map实现对所有command的注册管理。
二. TA框架还自己搞了一套注入,其实就是把原来findViewById的方式通过注解来实现。像这样:
public class ThinkAndroidMainActivity { @TAInjectView(id = R.id.test_db) Button testDBButton; @TAInjectView(id = R.id.test_cache) Button testCacheButton; @TAInjectView(id = R.id.test_image_cache) Button testImageCacheButton; @TAInjectView(id = R.id.test_mvc) Button testMVCCacheButton; @TAInjectView(id = R.id.test_http) Button testHTTPCacheButton; @TAInjectView(id = R.id.test_download) Button testDownloadButton; @TAInjectView(id = R.id.test_other) Button testOtherButton; @TAInjectView(id = R.id.exit_app) Button exitAppButton; }
具体的原理可参考上一篇讲自动测试的,道理是一样的。通过反射获取一个Activity,然后拿到所有加了这个注解的field,然后再做findViewById的动作,像这样:
field.set(activity, activity.findViewById(viewId));
我只能说,碉堡了。今天先讲到这里。
三. 网络监听模块
作者使用了静态广播来监听系统的网络连接状态,然后Application实现TANetChangeListener接口(作者这里没有用接口,不过小功能不必纠结),做为观察者监听该BroadcastReceiver,当系统的网络状态发生变化时,Application会收到通知,再把这个通知发给当前的Activity。但这样做似乎有个问题,若是其他非栈顶的Activity也需要监听这个状态来后台更新界面的时候就无法实现了。个人感觉应该让对这件事感兴趣的Activity自己观察BroadcastReceiver,或者Application在通知的时候通知所有栈中的Activity而不是只有栈顶的。
四.数据库模块
思想类似ORM框架。
1.TASQLiteDatabase是整个数据库功能逻辑的封装,TADBHelper则是封装的Android自带的SQliteOpenHelper,这里设定了一个TADBUpdateListener,用于上层监听数据库的更新。
2.创建数据库。
这里作者设计了一套数据库连接池TASQLiteDatabasePool来防止上层无止境地新建数据库导致性能低下,内存枯竭。数据库池对象和数据库名形成map,类似一个多例模式。Pool中通过一个Vector来管理所有的数据库连接,在获取时会先判断是否有空闲的连接,优先返回空闲的连接。在当前连接耗尽时,才创建新的连接,每次建立的连接数是一开始配置好的,并且最多不会超过最大的数据库连接。
3.创建表
这里又用到了注解和反射,让上层直接传入实体类,把具体的SQL对上层完全封装。看一个具体的Entity:
public class TestDataEntity implements Serializable { @TATransient private static final long serialVersionUID = -7995717179024306707L; @TAPrimaryKey(autoIncrement = true) int auto; @TAColumn(name = "username") String name; Date date; char c; @TACompareAnnotation(sortFlag = 0) int i; Boolean b; float f; double d; public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public char getC() { return c; } public void setC(char c) { this.c = c; } public int getI() { return i; } public void setI(int i) { this.i = i; } public Boolean getB() { return b; } public void setB(Boolean b) { this.b = b; } public float getF() { return f; } public void setF(float f) { this.f = f; } public double getD() { return d; } public void setD(double d) { this.d = d; } public int getAuto() { return auto; } public void setAuto(int auto) { this.auto = auto; } @Override public String toString() { return "getName" + getName() + "--getC--" + getC() + "--getD--" + getD() + "--getI--" + getI() + "--getF--" + getF() + "--getB--" + getB() + "--getDate--" + getDate() + "auto" + getAuto(); } }
创建表在TADBUtils里直接拼接了sql语句,没有用到TASqlBuilder。来看增删改查。
4.增删改查
这里用到了TASqlBuilderFactory来供上层生成对应的TASqlBuilder,简单工厂so easy。最大的好处就是不需要再去了解表的细节以及Android开发人员最不熟悉的sql语句,只要丢类进去就好了。依然是注解+反射。