GreenDao與ReactiveX的完美搭配

来源:http://www.cnblogs.com/cnwutianhao/archive/2017/04/16/6719380.html
-Advertisement-
Play Games

轉載請註明出處:http://www.cnblogs.com/cnwutianhao/p/6719380.html 作為Android開發者,一定不會對 GreenDao 和 ReactiveX 陌生。 GreenDao 號稱Android最快的關係型資料庫 ReactiveX 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開發資訊!
關註科技評論家,領略科技、創新、教育以及最大化人類智慧與想象力!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • DOM對象模型 【DOM樹節點】 DOM節點分為三大類:元素節點,文本節點,屬性節點: 文本節點,屬性節點為元素節點的兩個子節點; 通過getElment系列方法,可以去到元素節點; 【查看節點】 1.getElementById:通過id獲取唯一的節點;多個同名ID只會取到第一個; 2.etEle ...
  • 之前的某次番嗇看到油管上有這麼一個進度條,當時覺得挺好玩,一直想著做一個試試,剛纔弄了一下寫了一個不算太好看的簡陋版本,哈哈。 (本博客刷新會頭部會出現,因為並沒有真正的參與到瀏覽器載入是否完整這個渲染過程中來,所以只是一個表象,並不是說這個顯示完了就瀏覽器也載入完了所以資源。) ...
  • 一、簡介及安裝: gulp是前端開發過程中對代碼進行構建的工具,是自動化項目的構建利器;她不僅能對網站資源進行優化,而且在開發過程中很多重覆的任務能夠使用正確的工具自動完成;使用她,我們不僅可以很愉快的編寫代碼,而且大大提高我們的工作效率 gulp的優點:基於流的操作、任務化。 常用api:src ...
  • 雪花飄落的效果實現步驟:1.使用setInterval定時器每800毫秒創建一個雪花;2.把每一個雪花作為參數傳進動態下落的方法中即可。 js實現代碼: 效果圖如下: 這樣雪花飄落的效果就做好了。有什麼不足的地方請指正! ...
  • 在上一篇文章《iOS之ProtocolBuffer搭建和示例demo》分享環境的搭建, 我們和伺服器進行IM通訊用了github有名的框架CocoaAsynSocket, 然後和伺服器之間的數據媒介是ProtoBuf。然後後面在開發的過程中也碰到了拆包和粘包問題,這方面網上資料很少,曲折了一下才解決 ...
  • Android保持屏幕常亮,PowerManager.WakeLock的使用 需要在AndroidManifest.xml中添加許可權<uses-permission android:name="android.permission.WAKE_LOCK"/> SCREEN_BRIGHT_WAKE_LO ...
  • 在使用一些產品列如微信、QQ之類的,如果有新消息來時,手機屏幕即使在鎖屏狀態下也會亮起並提示聲音,這時用戶就知道有新消息來臨了。但是,一般情況下手機鎖屏後,Android系統為了省電以及減少CPU消耗,在一段時間後會使系統進入休眠狀態,這時,Android系統中CPU會保持在一個相對較低的功耗狀態。 ...
  • 第一步: 為mac電腦配置 adb 命令的環境變數,分為2小步 1.找到 Android Studio 為你安裝的 SDK : 打開電腦中 Android studio 的工具的軟體,在啟動 Android studio 的軟體的界面中,點擊下方列表中的”configure“的選項。在點擊列表中的“ ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...