GreenDao与Rx的完美搭配

转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6719380.html

作为Android开发者,一定不会对 GreenDao 和 ReactiveX 陌生。

GreenDao   号称Android最快的关系型数据库

ReactiveX    Rx是一个编程模型,目标是提供一致的编程接口,帮助开发者更方便的处理异步数据流。

下面我们就通过一个实例,来讲解有无Rx支持的时候GreenDao应该怎么用,实现增删操作。

首先导入需要的库(本文针对的 GreenDao 是 3.x 版本, Rx 是 1.x 版本)

GreenDao导入需求库的说明: https://github.com/greenrobot/greenDAO/

在 build.gradle(Project:Xxx) 下,添加:

buildscript {
    repositories {
        ...
        mavenCentral()
        ...
    }
    dependencies {
        ...
        classpath ‘org.greenrobot:greendao-gradle-plugin:3.2.2‘
        ...
    }
}

在 build.gradle(Module:Xxx) 下,添加:

...
apply plugin: ‘org.greenrobot.greendao‘
...
dependencies {
    ...
    compile ‘org.greenrobot:greendao:3.2.2‘
    ...
}

Rx导入需求库的说明: https://github.com/ReactiveX/RxJava/tree/1.x

在 build.gradle(Module:Xxx) 下,添加:

dependencies {
    ...
    compile ‘io.reactivex:rxjava:1.2.9‘
    compile ‘io.reactivex:rxandroid:1.2.1‘
    ...
}

需求库添加完之后就可以进入正题了

1.参考GreenDao官方文档,添加必要的类 Note 、 NotesAdapter 、 NoteType 、 NoteTypeConverter

Note :

/**
 * Entity mapped to table "NOTE".
 */
@Entity(indexes = {
        @Index(value = "text, date DESC", unique = true)
})
public class Note {

    @Id
    private Long id;

    @NotNull
    private String text;
    private String comment;
    private java.util.Date date;

    @Convert(converter = NoteTypeConverter.class, columnType = String.class)
    private NoteType type;

    @Generated(hash = 1272611929)
    public Note() {
    }

    public Note(Long id) {
        this.id = id;
    }

    @Generated(hash = 1686394253)
    public Note(Long id, @NotNull String text, String comment, java.util.Date date, NoteType type) {
        this.id = id;
        this.text = text;
        this.comment = comment;
        this.date = date;
        this.type = type;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @NotNull
    public String getText() {
        return text;
    }

    /**
     * Not-null value; ensure this value is available before it is saved to the database.
     */
    public void setText(@NotNull String text) {
        this.text = text;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public java.util.Date getDate() {
        return date;
    }

    public void setDate(java.util.Date date) {
        this.date = date;
    }

    public NoteType getType() {
        return type;
    }

    public void setType(NoteType type) {
        this.type = type;
    }

}

NotesAdapter :

public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.NoteViewHolder> {

    private NoteClickListener clickListener;
    private List<Note> dataset;

    public interface NoteClickListener {
        void onNoteClick(int position);
    }

    static class NoteViewHolder extends RecyclerView.ViewHolder {

        public TextView text;
        public TextView comment;

        public NoteViewHolder(View itemView, final NoteClickListener clickListener) {
            super(itemView);
            text = (TextView) itemView.findViewById(R.id.textViewNoteText);
            comment = (TextView) itemView.findViewById(R.id.textViewNoteComment);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (clickListener != null) {
                        clickListener.onNoteClick(getAdapterPosition());
                    }
                }
            });
        }
    }

    public NotesAdapter(NoteClickListener clickListener) {
        this.clickListener = clickListener;
        this.dataset = new ArrayList<Note>();
    }

    public void setNotes(@NonNull List<Note> notes) {
        dataset = notes;
        notifyDataSetChanged();
    }

    public Note getNote(int position) {
        return dataset.get(position);
    }

    @Override
    public NotesAdapter.NoteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_note, parent, false);
        return new NoteViewHolder(view, clickListener);
    }

    @Override
    public void onBindViewHolder(NotesAdapter.NoteViewHolder holder, int position) {
        Note note = dataset.get(position);
        holder.text.setText(note.getText());
        holder.comment.setText(note.getComment());
    }

    @Override
    public int getItemCount() {
        return dataset.size();
    }
}

NoteType :

public enum NoteType {
    TEXT, LIST, PICTURE
}

NoteTypeConverter :

public class NoteTypeConverter implements PropertyConverter<NoteType, String> {
    @Override
    public NoteType convertToEntityProperty(String databaseValue) {
        return NoteType.valueOf(databaseValue);
    }

    @Override
    public String convertToDatabaseValue(NoteType entityProperty) {
        return entityProperty.name();
    }
}

必要的类添加之后,接下来就是重头戏:

用代码说话,横向比较 GreenDao 在有无 Rx 的支持下应该如何书写

1.初始化类

无 Rx 写法

private NoteDao noteDao;
private Query<Note> notesQuery;

有 Rx 写法

private RxDao<Note, Long> noteDao;
private RxQuery<Note> notesQuery;

2.将记录保存到DAO里

无 Rx 写法

DaoSession daoSession = ((BaseApplication) getApplication()).getDaoSession();
noteDao = daoSession.getNoteDao();

有 Rx 写法

DaoSession daoSession = ((BaseApplication) getApplication()).getDaoSession();
noteDao = daoSession.getNoteDao().rx();

3.查询所有记录,按A-Z分类

无 Rx 写法

notesQuery = noteDao.queryBuilder().orderAsc(NoteDao.Properties.Text).build();

有 Rx 写法

notesQuery = daoSession.getNoteDao().queryBuilder().orderAsc(NoteDao.Properties.Text).rx();

4.初始化View

无 Rx 写法

protected void setUpViews() {
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerViewNotes);
        //noinspection ConstantConditions
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        notesAdapter = new NotesAdapter(noteClickListener);
        recyclerView.setAdapter(notesAdapter);

        addNoteButton = findViewById(R.id.buttonAdd);
        //noinspection ConstantConditions
        addNoteButton.setEnabled(false);

        editText = (EditText) findViewById(R.id.editTextNote);
        editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {

            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    addNote();
                    return true;
                }
                return false;
            }
        });
        editText.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                boolean enable = s.length() != 0;
                addNoteButton.setEnabled(enable);
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });
    }

有 Rx 写法

protected void setUpViews() {
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerViewNotes);
        //noinspection ConstantConditions
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        notesAdapter = new NotesAdapter(noteClickListener);
        recyclerView.setAdapter(notesAdapter);

        addNoteButton = findViewById(R.id.buttonAdd);

        editText = (EditText) findViewById(R.id.editTextNote);
        //noinspection ConstantConditions
        RxTextView.editorActions(editText).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer actionId) {
                        if (actionId == EditorInfo.IME_ACTION_DONE) {
                            addNote();
                        }
                    }
                });
        RxTextView.afterTextChangeEvents(editText).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<TextViewAfterTextChangeEvent>() {
                    @Override
                    public void call(TextViewAfterTextChangeEvent textViewAfterTextChangeEvent) {
                        boolean enable = textViewAfterTextChangeEvent.editable().length() > 0;
                        addNoteButton.setEnabled(enable);
                    }
                });
    }

5.更新记录

无 Rx 写法

private void updateNotes() {
    List<Note> notes = notesQuery.list();
    notesAdapter.setNotes(notes);
}

有 Rx 写法

private void updateNotes() {
    notesQuery.list()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<List<Note>>() {
                @Override
                public void call(List<Note> notes) {
                    notesAdapter.setNotes(notes);
                }
            });
}

6.添加记录

无 Rx 写法

private void addNote() {
        String noteText = editText.getText().toString();
        editText.setText("");

        final DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
        String comment = "Added on " + df.format(new Date());

        Note note = new Note();
        note.setText(noteText);
        note.setComment(comment);
        note.setDate(new Date());
        note.setType(NoteType.TEXT);
        noteDao.insert(note);
        Log.d("DaoExample", "Inserted new note, ID: " + note.getId());

        updateNotes();
    }

有 Rx 写法

private void addNote() {
        String noteText = editText.getText().toString();
        editText.setText("");

        final DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
        String comment = "Added on " + df.format(new Date());

        Note note = new Note(null, noteText, comment, new Date(), NoteType.TEXT);
        noteDao.insert(note)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Note>() {
                    @Override
                    public void call(Note note) {
                        Log.d("DaoExample", "Inserted new note, ID: " + note.getId());
                        updateNotes();
                    }
                });
    }

7.删除记录

无 Rx 写法

NotesAdapter.NoteClickListener noteClickListener = new NotesAdapter.NoteClickListener() {
        @Override
        public void onNoteClick(int position) {
            Note note = notesAdapter.getNote(position);
            Long noteId = note.getId();

            noteDao.deleteByKey(noteId);
            Log.d("DaoExample", "Deleted note, ID: " + noteId);

            updateNotes();
        }
    };

有 Rx 写法

NotesAdapter.NoteClickListener noteClickListener = new NotesAdapter.NoteClickListener() {
        @Override
        public void onNoteClick(int position) {
            Note note = notesAdapter.getNote(position);
            final Long noteId = note.getId();

            noteDao.deleteByKey(noteId)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Action1<Void>() {
                        @Override
                        public void call(Void aVoid) {
                            Log.d("DaoExample", "Deleted note, ID: " + noteId);
                            updateNotes();
                        }
                    });
        }
    };

最后别忘了新建一个Application类,并添加到Manifest中

public class BaseApplication extends Application {

    /**
     * A flag to show how easily you can switch from standard SQLite to the encrypted SQLCipher.
     */
    public static final boolean ENCRYPTED = true;

    private DaoSession daoSession;

    @Override
    public void onCreate() {
        super.onCreate();

        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(                this, ENCRYPTED ? "notes-db-encrypted" : "notes-db");
        Database db = ENCRYPTED ? helper.getEncryptedWritableDb("super-secret") : helper.getWritableDb();
        daoSession = new DaoMaster(db).newSession();
    }

    public DaoSession getDaoSession() {
        return daoSession;
    }

}

文中额外可能会用到的库

compile ‘com.jakewharton.rxbinding:rxbinding:1.0.1‘
compile ‘net.zetetic:android-database-sqlcipher:3.5.6‘

关注我的新浪微博,获取更多Android开发资讯!
关注科技评论家,领略科技、创新、教育以及最大化人类智慧与想象力!

时间: 2024-10-21 09:29:05

GreenDao与Rx的完美搭配的相关文章

LESS-Middleware:Node.js 和 LESS 的完美搭配

LESS 是一个编写 CSS 的很好的方式 ,让你可以使用变量,嵌套规则,混入以及其它许多有用的功能,它可以帮助您更好地组织你的 CSS 代码. 最近我一直在研究 Node.js ,并想用 less-middleware 中间件,这样我可以很容易的在我的应用程序中使用 LESS 了.配置好以后,LESS-Middleware 能够自动处理编译你的 LESS 代码为 CSS 代码. 如果你把 LESS 和 CSS 文件存储在同一个目录,配置很简单,但我想用不同的路径为我的源目录和目标目录,这个地方

HDU4685 Prince and Princess 完美搭配+良好的沟通

意甲冠军:今天,有n王子,m公主.现在给他们配对,与王子会嫁给一个男人,他喜欢.公主无法做出选择. 这标题去咬硬,还有一类似的题目poj1904.那个题目也是给王子与公主配对,但那个是王子公主各n个,且给定了一个完美匹配,然后求每一个王子能够做出的选择且不影响最大匹配数目.那题是先建各条喜欢关系的边.然后在由被选择的公主连一条边到与之配对的王子.强连通之后假设一个王子和一个公主在一个强连通分量中,那么他们结合的话,他们的还有一半也各自能在强连通中找到另外的匹配,就是符合题意的结果了. 这个题目算

asp.net mvc 加三层架构 完美搭配

http://www.hysql.org/aspnet/20180630/5712.html 先来一张项目的层级结构图: Model:模型层,主要是各种类型.枚举以及ORM框架,框架完成数据库和实体类的映射.项目中选用了微软的开源ORM框架 EntityFramework 6.0 (以下简称EF),数据库则选择了微软的轻量级数据库SQL Server Compact 4.0本地数据库(简称Compact),Compact对EF支持比较完美,又属于文档型数据库,部署起来比较简洁. DAL:数据访问

[转] 传统 Ajax 已死,Fetch 永生

原谅我做一次标题党,Ajax 不会死,传统 Ajax 指的是 XMLHttpRequest(XHR),未来现在已被 Fetch 替代. 最近把阿里一个千万级 PV 的数据产品全部由 jQuery 的 $.ajax 迁移到 Fetch,上线一个多月以来运行非常稳定.结果证明,对于 IE8+ 以上浏览器,在生产环境使用 Fetch 是可行的. 由于 Fetch API 是基于 Promise 设计,有必要先学习一下 Promise,推荐阅读 MDN Promise 教程.旧浏览器不支持 Promis

LevelDB初体验测试

最近工作需要找一个能使用磁盘存储数据,对写要求比较苛刻,需要每秒达100000TPS,读的时候需要能10000TPS左右,不能占用太多内存.单节点满足这个要求的常见有Redis.Memcached等,但是这个东西太费内存了,代价比较高,不太合适.找来找去,找到Leveldb这个神器了,在写的时候对内存要求不高,读的时候根据性能要求的不同需要对应的内存,如果使用SSD就是完美搭配了. 目前主要测试写入性能,发现Leveldb还是使用单线程插入最为高效,但是写入性能非常惊人.  测试数据: key=

CDN是什么?

1. CDN的概念 CDN的全称是Content Delivery Network,即内容分发网络,这是专业术语,对于普通用户来讲很难听得懂.我们用通俗易懂的话来讲就是,把我们的网站部署至全国各地的服务器上,然后让用户就近访问,那么这种新型网络构建方式就是CDN,我们部署网站的服务器,也就被称之为CDN节点.当我们网站内容有更新时,CDN节点会自动请求源网站索引我们网站的最新内容.网站接入CDN提升网站打开速度至少30%以上.  2.CDN的基本思路 CDN的基本思路是尽可能避开互联网上有可能影

豆腐的营养秘密

豆腐是我们日常生活中常见的食物,也是餐桌上必不可少的美食.豆腐也是做法不同有不同的味道,那么怎么把豆腐做成最营养的美食,那就需要多学习选择一些比较好的食材来跟豆腐搭配,密封单轴圆形挡板门,让它发挥超常的营养价值,也让我们因为吃了营养豆腐而使身体更加棒.     加牛奶,补钙养肺 牛奶和豆腐堪称完美搭配,一个是植物蛋白,一个是动物蛋白,合二为一,自然效果是强强联合. 加蛋黄.血豆腐,钙补得更多. 就像吃钙片的同时要补维生素D一样,吃豆腐要补钙,就要搭配一些维D丰富的食物.因为在钙的吸收利用过程中,

iOS-Core-Animation-Advanced-Techniques(二)

视觉效果和变换 (四)视觉效果 嗯,园和椭圆还不错,但如果是带圆角的矩形呢? 我们现在能做到那样了么? 史蒂芬·乔布斯 我们在第三章『图层几何学』中讨论了图层的frame,第二章『寄宿图』则讨论了图层的寄宿图.但是图层不仅仅可以是图片或是颜色的容器:还有一系列内建的特性使得创造美丽优雅的令人深刻的界面元素成为可能.在这一章,我们将会探索一些能够通过使用CALayer属性实现的视觉效果. 圆角 圆角矩形是iOS的一个标志性审美特性.这在iOS的每一个地方都得到了体现,不论是主屏幕图标,还是警告弹框

为革命保护视力 --- 给 Visual Studio 换颜色

为革命保护视力 --- 给 Visual Studio 换颜色 "为革命,保护视力,预防近视,眼保健操开始......" 这个应该是最老版本的眼保健操了,你听过? 一堆废话 且不说上面这个眼保健操到底有木有用,让眼睛放松下还是很有必要的,尤其是现在天天对着不是手机.平板就是电脑,前阵子还听说有人因为长时间玩手机,导致失明的.所以,同志们,赶紧放松下眼睛吧~~~ 作为一位码农,经常需要一连几小时盯着屏幕敲键盘,时间长了眼睛就会很疲劳,工作效率就会受到影响,你知道为什么容易疲劳吗? 日本东