先呵呵一下碎屏保。
框架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语句,只要丢类进去就好了。依然是注解+反射。