針對我的項目藉機系統中,數據管理問題給出解決方案。爲了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代碼返回給界面顯示。
目前能想到的最好方案就是這樣了,肯定還有更好的方案。後面會接着改善。