首页 > 学院 > 开发设计 > 正文

使用Realm进行数据操作(二)

2019-11-08 00:37:36
字体:
来源:转载
供稿:网友

Realm的异步操作

  在上一篇中使用了Realm的事务操作,实现了数据的增删改查。但是在执行增删改后,我们没法知道,数据是否发生改变了。反正我个人是比较菜,没找到啥方法能获取到数据是否发生改变。还好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(); } }

Realm的异步任务(查询)

  到了查询这就不能用上面的方法了,它有自己单独的方法。

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) { //查询结结束 } });

例子中的增删改查操作

1、异步增

/** * 添加数据 */ @Override public void insertDataToRealm(final Food food) { insertTask = realm.executeTransactionAsync(new Realm.Transaction() { @Override public void execute(Realm realm) {//执行异步操作 Log.w("insertDataToRealm", "execute: "); Log.i("线程", Thread.currentThread().getName()); realm.copyToRealm(food); } }, new Realm.Transaction.OnSuccess() {//操作成功 @Override public void onSuccess() { Toast.makeText(AsyncActivity.this,"添加成功!",Toast.LENGTH_SHORT).show(); Log.i("insertDataToRealm", "onSuccess: "); Log.i("线程", Thread.currentThread().getName()); selectAllDataFromRealm(); } }, new Realm.Transaction.OnError() { @Override public void onError(Throwable error) { Log.d("线程", Thread.currentThread().getName()); Log.d("onError", error.getMessage()); } }); }

2、异步删

* 删除数据 * @param foodName */ @Override public void deleteDataToRealm(final String foodName) { deleteTask = realm.executeTransactionAsync(new Realm.Transaction() { @Override public void execute(Realm realm) { //条件查询 Food food = realm.where(Food.class).equalTo("name",foodName).findFirst(); food.deleteFromRealm();//删除数据 } }, new Realm.Transaction.OnSuccess() { @Override public void onSuccess() { Toast.makeText(AsyncActivity.this,"删除成功!",Toast.LENGTH_SHORT).show(); selectAllDataFromRealm(); } }); }

3、异步改

/** * 更新数据 * @param foodName */ @Override public void updataToRealm(final String foodName , final double price) { updataTask = realm.executeTransactionAsync(new Realm.Transaction() { @Override public void execute(Realm realm) { //条件查询 Food food = realm.where(Food.class).equalTo("name",foodName).findFirst(); food.setPrice(price);//更改价格 } }, new Realm.Transaction.OnSuccess() { @Override public void onSuccess() { selectAllDataFromRealm(); Toast.makeText(AsyncActivity.this,"修改成功!",Toast.LENGTH_SHORT).show(); } }); }

4、异步查

/** * 异步全查询 */ private void selectAllDataFromRealm(){ foods = realm.where(Food.class).findAllAsync(); foods.addChangeListener(new RealmChangeListener<RealmResults<Food>>() { @Override public void onChange(RealmResults<Food> element) { Log.d("selectAllDataFromRealm", "查询到结果"); Log.i("线程", Thread.currentThread().getName()); List<Food> result = realm.copyFromRealm(foods); if (result.size() == 0){ Log.d("结果集", "没有数据"); return; } for (Food food : result){ Log.d("结果集", "------------------------------"); Log.w("类别", food.getType()); Log.w("名称", food.getName()); Log.w("价格", food.getPrice()+""); } if (foods.isLoaded()){ foods.removeChangeListeners(); } } }); }

使用RealmBaseAdapter

  使用起来需添加依赖:

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地址


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表