在上一篇中使用了Realm的事務(wù)操作,實(shí)現(xiàn)了數(shù)據(jù)的增刪改查。但是在執(zhí)行增刪改后,我們沒(méi)法知道,數(shù)據(jù)是否發(fā)生改變了。反正我個(gè)人是比較菜,沒(méi)找到啥方法能獲取到數(shù)據(jù)是否發(fā)生改變。還好Realm本身支持異步操作并帶有回調(diào)監(jiān)聽(tīng)。使我又找到了學(xué)習(xí)的信心,然后實(shí)踐了一下。

根據(jù)參考的資料來(lái)看,使用一個(gè)異步操作是挺簡(jiǎn)單的。因?yàn)椴襟E基本都是死的。基本步驟如下:
1.聲明一個(gè)全局變量(為啥用全局變量,因?yàn)槿绻蚁胍诮缑驿N(xiāo)毀時(shí),同時(shí)取消未完成的異步任務(wù)我只能這嗎做?。? PRivate RealmAsyncTask insertTask,updataTask,deleteTask;//異步添加任務(wù)2.創(chuàng)建異步任務(wù): 創(chuàng)建RealmAsyncTask有四種方法,當(dāng)然了它們都是重載方法。用哪個(gè)就看是啥需求了。 
這里與帶三個(gè)參數(shù)的方法為例,我們來(lái)看一下這三個(gè)參數(shù)都是干嘛的。
RealmAsyncTask task = realm.executeTransactionAsync(new Realm.Transaction() { @Override public void execute(Realm realm) { //執(zhí)行異步操作-->執(zhí)行線程子線程 } }, new Realm.Transaction.OnSuccess() { @Override public void onSuccess() { //操作成果-->執(zhí)行線程主線程 } }, new Realm.Transaction.OnError() { @Override public void onError(Throwable error) { //操作失敗-->執(zhí)行線程主線程 } });因?yàn)檫@三個(gè)參數(shù)都是接口的實(shí)現(xiàn)類(lèi)同時(shí)還都是匿名內(nèi)部類(lèi),所以還可以使用Lambda表達(dá)式進(jìn)行一下代碼的簡(jiǎn)化。于是代碼就變成了這樣(如果不使用retrolambda插件的話,要注意一下亂碼的問(wèn)題)。
RealmAsyncTask task = realm .executeTransactionAsync( realm1 -> Log.i("子線程", "執(zhí)行異步操作!"), () -> Log.i("主線程", "操作成功!"), error -> Log.i("主線程", "操作失敗!"));3.在界面銷(xiāo)毀的時(shí)候,取消未完成的異步任務(wù) 容我大膽的瞎說(shuō)一下,這個(gè)跟退出界面后關(guān)閉子Thread和關(guān)閉動(dòng)畫(huà)(動(dòng)畫(huà)內(nèi)部也是使用線程來(lái)實(shí)現(xiàn)的)的原理一樣,都是為了防止內(nèi)存泄漏。于是便在Activity或者Fragment的onDestory()方法中取消了未完成的異步任務(wù)。代碼如下: @Override protected void onDestroy() { cancelTask(insertTask); cancelTask(updataTask); cancelTask(deleteTask); realm.close(); super.onDestroy(); } private void cancelTask(RealmAsyncTask task){ if (task!=null&&!task.isCancelled()){ task.cancel(); } }到了查詢(xún)這就不能用上面的方法了,它有自己?jiǎn)为?dú)的方法。
1.全查詢(xún) RealmResults<Food> foods = realm.where(Food.class).findAllAsync(); foods.addChangeListener(new RealmChangeListener<RealmResults<Food>>() { @Override public void onChange(RealmResults<Food> element) { //查詢(xún)結(jié)束 } });2.條件查詢(xún)并返回第一個(gè)結(jié)果 Food food = realm.where(Food.class).equalTo("name","A").findFirstAsync(); food.addChangeListener(new RealmChangeListener<RealmModel>() { @Override public void onChange(RealmModel element) { //查詢(xún)結(jié)結(jié)束 } });使用起來(lái)需添加依賴(lài):
compile 'io.realm:android-adapters:1.4.0'這里我用了Rxjava1(RxJava)來(lái)結(jié)合Realm來(lái)執(zhí)行異步查詢(xún),因?yàn)镽ealm支持RxJava。所以又添加了兩個(gè)依賴(lài):
compile 'io.reactivex:rxandroid:1.2.1'compile 'io.reactivex:rxjava:1.1.6'1.創(chuàng)建適配器/** * Author LYJ * Created on 2017/2/23. * Time 16:00 */public class TestAdapter extends RealmBaseAdapter<Food> implements ListAdapter { public TestAdapter(@NonNull Context context, @Nullable OrderedRealmCollection<Food> data) { super(context, data); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView == null) { convertView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item, parent, false); viewHolder = new ViewHolder(convertView); viewHolder.name = ButterKnife.findById(convertView,R.id.name); viewHolder.price = ButterKnife.findById(convertView,R.id.price); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } Food food = adapterData.get(position); viewHolder.name.setText(food.getName()); viewHolder.price.setText(String.valueOf(food.getPrice())); return convertView; } static class ViewHolder { @BindView(R.id.name) TextView name; @BindView(R.id.price) TextView price; ViewHolder(View view) { ButterKnife.bind(this, view); } }}2.查詢(xún)數(shù)據(jù)后加載數(shù)據(jù) /** * 加載數(shù)據(jù) */ private void add() { realm.where(Food.class) .findAllAsync() .asObservable() .observeOn(AndroidSchedulers.mainThread()) .subscribe(foods -> { listview.setAdapter(new TestAdapter(context,foods)); }); }Demo地址
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注