在上一篇中使用了Realm的事务操作,实现了数据的增删改查。但是在执行增删改后,我们没法知道,数据是否发生改变了。反正我个人是比较菜,没找到啥方法能获取到数据是否发生改变。还好Realm本身支持异步操作并带有回调监听。使我又找到了学习的信心,然后实践了一下。
根据参考的资料来看,使用一个异步操作是挺简单的。因为步骤基本都是死的。基本步骤如下:
1.声明一个全局变量(为啥用全局变量,因为如果我想要在界面销毁时,同时取消未完成的异步任务我只能这吗做!): PRivate RealmAsyncTask insertTask,updataTask,deleteTask;//异步添加任务2.创建异步任务: 创建RealmAsyncTask有四种方法,当然了它们都是重载方法。用哪个就看是啥需求了。
这里与带三个参数的方法为例,我们来看一下这三个参数都是干嘛的。
RealmAsyncTask task = realm.executeTransactionAsync(new Realm.Transaction() { @Override public void execute(Realm realm) { //执行异步操作-->执行线程子线程 } }, new Realm.Transaction.OnSuccess() { @Override public void onSuccess() { //操作成果-->执行线程主线程 } }, new Realm.Transaction.OnError() { @Override public void onError(Throwable error) { //操作失败-->执行线程主线程 } });因为这三个参数都是接口的实现类同时还都是匿名内部类,所以还可以使用Lambda表达式进行一下代码的简化。于是代码就变成了这样(如果不使用retrolambda插件的话,要注意一下乱码的问题)。
RealmAsyncTask task = realm .executeTransactionAsync( realm1 -> Log.i("子线程", "执行异步操作!"), () -> Log.i("主线程", "操作成功!"), error -> Log.i("主线程", "操作失败!"));3.在界面销毁的时候,取消未完成的异步任务 容我大胆的瞎说一下,这个跟退出界面后关闭子Thread和关闭动画(动画内部也是使用线程来实现的)的原理一样,都是为了防止内存泄漏。于是便在Activity或者Fragment的onDestory()方法中取消了未完成的异步任务。代码如下: @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(); } }到了查询这就不能用上面的方法了,它有自己单独的方法。
1.全查询 RealmResults<Food> foods = realm.where(Food.class).findAllAsync(); foods.addChangeListener(new RealmChangeListener<RealmResults<Food>>() { @Override public void onChange(RealmResults<Food> element) { //查询结束 } });2.条件查询并返回第一个结果 Food food = realm.where(Food.class).equalTo("name","A").findFirstAsync(); food.addChangeListener(new RealmChangeListener<RealmModel>() { @Override public void onChange(RealmModel element) { //查询结结束 } });使用起来需添加依赖:
compile 'io.realm:android-adapters:1.4.0'这里我用了Rxjava1(RxJava)来结合Realm来执行异步查询,因为Realm支持RxJava。所以又添加了两个依赖:
compile 'io.reactivex:rxandroid:1.2.1'compile 'io.reactivex:rxjava:1.1.6'1.创建适配器/** * 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.查询数据后加载数据 /** * 加载数据 */ private void add() { realm.where(Food.class) .findAllAsync() .asObservable() .observeOn(AndroidSchedulers.mainThread()) .subscribe(foods -> { listview.setAdapter(new TestAdapter(context,foods)); }); }Demo地址
新闻热点
疑难解答