针对我的项目借机系统中,数据管理问题给出解决方案。为了UI显示数据的流畅性,数据管理也必须采取异步方案。android原生提供了一些异步类AysncTask等,也可以采用Thread+Handler的方案。但我目前遇到的问题是这样的,比如添加手机功能,我需要先上传到网络服务器,成功后再添加到本地数据库。还有获取数据也是,我需要先从网络服务器获取数据,如果未联网,我需要从本地数据库来获取数据。针对这些问题,都会涉及到多次回调,用android原生的方法解决起来很繁琐。于是找到了网上比较流行的RXjava异步方案。学习之后,开始用到自己的项目当中,如添加手机代码:
public void addPhone(final PhoneNote phoneNote) {
if (phoneNote == null) {
throw new IllegalArgumentException();
}
Observable network_observable = Observable.create(new Observable.OnSubscribe<Boolean>() {
@Override
public void call(Subscriber<? super Boolean> subscriber) {
if (NetUtil.isNetworkConnected(LendPhoneApplication.getAppContext())) {
if (addPhoneNetWork(phoneNote)) {
subscriber.onCompleted();
} else {
subscriber.onNext(false);
}
} else {
subscriber.onNext(false);
}
}
});
Observable database_observable = Observable.create(new Observable.OnSubscribe<Boolean>() {
@Override
public void call(Subscriber<? super Boolean> subscriber) {
addPhoneTable(phoneNote);
subscriber.onNext(true);
}
});
Observable.concat(network_observable, database_observable)
.first()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Boolean aBoolean) {
if (mView != null) {
mView.onResult(aBoolean);
}
}
});
}
先执行network_observable中的事件,检查网络,没有网络就直接返回false,有网络的情况下,如果添加到网络成功,则接着执行database_observable中的事件,将数据添加到数据库中,成功后返回true。
下面看下获取数据代码:
public void loadData() {
Observable network_observable = Observable.just("network")
.map(new Func1<String, List<PhoneNote>>() {
@Override
public List<PhoneNote> call(String s) {
List<PhoneNote> phoneNotes = null;
if (NetUtil.isNetworkConnected(LendPhoneApplication.getAppContext())) {
phoneNotes = null;//从网络获取
if (phoneNotes == null) {
phoneNotes = mDataBaseAction.query();//从数据库获取
}
} else {
phoneNotes = mDataBaseAction.query();
}
return phoneNotes;
}
}).map(new Func1<List<PhoneNote>, List<PhoneNoteModel>>() {
@Override
public List<PhoneNoteModel> call(List<PhoneNote> phoneNotes) {
return phoneNotes == null ? null : getConvertPhoneData(phoneNotes);
}
});
Subscriber subscriber = new Subscriber<List<PhoneNoteModel>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
LogHelper.logD(TAG, e.toString());
}
@Override
public void onNext(List<PhoneNoteModel> phoneNoteModels) {
if (mView != null)
mView.onFetchedPhones(phoneNoteModels);
}
};
network_observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
}
获取数据会输入url(这里的network字符串替代),首先判断网络情况,如果没有联网就从数据库获取,如果连网络了就从网路服务器获取,获取失败再从数据库获取。获取数据后,接着要进行数据转换将List<PhoneNote>转换为List<PhoneNoteModel>方便UI取数据。转化完后回到主线程调用订阅者的onNext代码返回给界面显示。
目前能想到的最好方案就是这样了,肯定还有更好的方案。后面会接着改善。