为什么要使用异步操作?
LitePal操作SQLite数据库,是一种表面上看起来不耗时,数据一多实则会耗时的操作。主线程中直接操作数据库也可以,但是会影响UI更新,典型的现象就是刷新数据短暂的卡顿,也是会感觉不流畅,页面跳转也会短暂的卡顿。这个时候,就需要考虑开启独立的线程来操作数据库了。
参考:https://mp.weixin.qq.com/s/GXPkrkiHk4MWNnpCLzTf_Q
支持异步操作数据库是LitePal 1.5.0版本的核心功能。在这之前,使用LitePal操作数据库默认都是在主线程进行的,如果你想在子线程中进行数据库操作则需要自己创建线程才行。
事实上,Android官方是建议将所有的数据库操作都放在子线程中进行的。但是我们大多数情况下可能都不会这么做,因为数据库操作一般都很快,即使在主线程中执行也基本不会影响到界面元素。因此,LitePal之前的版本中也是一直都没有加入异步操作数据库这个功能。
但是凡事都有例外,如果你需要对大量的数据进行操作,比如从数据库中读取几千甚至上万条记录,这个时候如果还放在主线程中操作显然就不是一个明智的选择,因此异步操作数据库还是有它适用的场景的。
也是听了很多朋友的建议,于是我开始设计异步操作数据库这个功能。在设计的时候,我要充分考虑到它的易用性,因为我希望可以让原本就已经了解LitePal用法的开发者们立即就能上手这个新功能,而不需要付出什么额外的学习成本。
经过了长时间的思考,我给LitePal中所有的CRUD方法都加入了一个Async的副本方法。什么意思呢?比如说原来有一个find()方法,现在就会多出一个findAsycn()方法,原来有一个save()方法,现在就会多出一个saveAsync()方法。如果你想要进行异步数据库操作的时候,只要去调用原API相对应的Async副本方法就可以了。
但是由于异步操作的内部会开启线程,因此这类方法都是无法返回值的,那么异步操作的结果就只能依靠回调来完成。所以,我又给每一个Async副本方法的后面添加了一个listen()方法,专门用于监听异步操作的结果。
另外还有一点需要说明,虽然Async方法内部会开启子线程,但是所有异步操作回调到onFinish()方法之后都会切回到主线程。也就是说,大家可以直接在这里进行UI操作,弹出Toast提示等等,而不需要自己再进行一次线程切换了。这也是LitePal为了方便大家开发又做出的一些优化。
保存操作:
数据一条的时候使用:
CRM_DT_BAOGAO model2 = new CRM_DT_BAOGAO();
List<CRM_DT_BAOGAO> list2 = DataSupport.where("MAIN_ID = ?", ID).find(CRM_DT_BAOGAO.class);
if (list2.size() == 0) {
//不存在
model2.setMAIN_ID(ID);
model2.setSGDWMC(SGDWMC);
model2.setSGZBH(SGZBH);
model2.setSGLB(SGLB);
model2.setXCJYTJ(XCJYTJ);
model2.setBEIZHU(BEIZHU);
model2.setJJ_DATE_S(JJ_DATE_S);
model2.setJJ_DATE_E(JJ_DATE_E);
model2.setJYRY(JYRY);
model2.setJHRY(JHRY);
if (model2.save()) {
System.out.println("CRM_DT_BAOGAO 写入成功");
} else {
System.out.println("CRM_DT_BAOGAO 写入失败");
}
数据多条的时候使用:
List<CRM_DTYEYA_JDJYXM_ANS> list1 = new ArrayList<CRM_DTYEYA_JDJYXM_ANS>();
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = ja.getJSONObject(i);
String JYJG = jo.getString("jyjg").equals("null") ? "" : jo.getString("jyjg");
String SHUJU = jo.getString("shuju").equals("null") ? "" : jo.getString("shuju");
String XM_ID = jo.getString("id").equals("null") ? "" : jo.getString("id");
CRM_DTYEYA_JDJYXM_ANS model = new CRM_DTYEYA_JDJYXM_ANS();
model.setJYJG(JYJG);
model.setSHUJU(SHUJU);
model.setXM_ID(XM_ID);
model.setJYJL_ID(ID);
list1.add(model);
}
DataSupport.saveAllAsync(list1).listen(new SaveCallback() {
@Override
public void onFinish(boolean success) {
saveResult = success;
}
});
查询操作:
有两个查询语句的关联,异步查询嵌套。EventBus回调结果
//异步查询
DataSupport.findAllAsync(CRM_DTYY_DQJYXM.class).listen(new FindMultiCallback() {
@Override
public <T> void onFinish(List<T> t) {
final List<CRM_DTYY_DQJYXM> list2 = (List<CRM_DTYY_DQJYXM>) t;
DataSupport.where("JYJL_ID = ?", ID).findAsync(CRM_DTYY_DQJYXM_ANS.class).listen(new FindMultiCallback() {
@Override
public <T> void onFinish(List<T> t) {
final List<CRM_DTYY_DQJYXM_ANS> list21 = (List<CRM_DTYY_DQJYXM_ANS>) t;
if (list2.size() != 0) {
String json = "[";
for (int i = 0; i < list2.size(); i++) {
if (list21.size() == 0) {
//结果表为空
//gson
Gson gson = new GsonBuilder().serializeNulls().create();
HashMap<String, Object> map = new HashMap<>();
map.put("ID",list2.get(i).getMYID());
map.put("JYLB",list2.get(i).getJYLB());
map.put("YJ",list2.get(i).getYJ());
map.put("EJ",list2.get(i).getEJ());
map.put("SJ",list2.get(i).getSJ());
map.put("SEQ",list2.get(i).getSEQ());
map.put("SEQ_JL",list2.get(i).getSEQ_JL());
map.put("JYJG","符合");
map.put("SHUJU", null);
json += gson.toJson(map) + ",";
}else {
for (int j = 0; j < list21.size(); j++) {
//CRM_DTYY_JDJYXM_ANS . XM_ID = CRM_DTYY_JDJYXM . ID
if (list2.get(i).getMYID().equals(list21.get(j).getXM_ID())) {
//Gson
Gson gson = new GsonBuilder().serializeNulls().create();
HashMap<String, Object> map = new HashMap<>();
map.put("ID",list2.get(i).getMYID());
map.put("JYLB",list2.get(i).getJYLB());
map.put("YJ",list2.get(i).getYJ());
map.put("EJ",list2.get(i).getEJ());
map.put("SJ",list2.get(i).getSJ());
map.put("SEQ",list2.get(i).getSEQ());
map.put("SEQ_JL",list2.get(i).getSEQ_JL());
map.put("JYJG",list21.get(j).getJYJG());
map.put("SHUJU", list21.get(j).getSHUJU());
json += gson.toJson(map) + ",";
}
}
}
}
json = json.substring(0, json.length() - 1) + "]";
//发送黏性事件
EventBus.getDefault().postSticky(new MyJson2Webview(json));
}
}
});
}
});
//异步操作 事件处理
@Subscribe(threadMode = ThreadMode.POSTING,sticky = true)
public void MyJson2Webview(MyJson2Webview myJson2Webview) {
jsonDb = myJson2Webview.getJson();
//防止转义
jsonDb = jsonDb.replace("\n","\\n").replace("\r","\\r").replace("\r\n","\\r\\n");
webView.addJavascriptInterface(new JSBridge(), "android");
}