前言:
在現(xiàn)在不懂就google的時(shí)代開發(fā)本身已經(jīng)不是什么難事了鸠踪,能夠開速寫出優(yōu)雅,靈活复斥,易擴(kuò)展营密,高性能的代碼是我們不斷學(xué)習(xí)和需要努力的目標(biāo)。隨著Android發(fā)展許多新的技術(shù)和框架需要我們?nèi)W(xué)習(xí)和深入目锭。下面引用一張圖片來表達(dá)我想要實(shí)現(xiàn)的Android應(yīng)用架構(gòu)圖卵贱。
對(duì)于MVP架構(gòu)的優(yōu)點(diǎn)大家可以自行搜索,本文不在這里討論MVP和傳統(tǒng)MVC模式的優(yōu)劣侣集。
- Model:數(shù)據(jù)層 键俱,數(shù)據(jù)來源通常是文件,數(shù)據(jù)庫世分,服務(wù)器
1 . 數(shù)據(jù)庫分別使用GreenDao框架和LiteOrm來實(shí)現(xiàn)编振。
2 . 服務(wù)器接口調(diào)用采用 Retrofit:Square提供的開源產(chǎn)品,為Android平臺(tái)的應(yīng)用提供一個(gè)類型安全的REST客戶端,其他的網(wǎng)絡(luò)框架Volley臭埋,Okhttp等大家可以對(duì)比下 - View:UI顯示層 踪央,通常是由activity,fragment,自定義的viewGroup等組成
- Presenter:中間層 瓢阴,負(fù)責(zé)View和Model的各種邏輯處理包括數(shù)據(jù)庫操作畅蹂,網(wǎng)絡(luò)數(shù)據(jù)請(qǐng)求等等
- RxJava 和傳統(tǒng)編程思維不太一樣,基于觀察者模式對(duì)數(shù)據(jù)流的操作非常方便荣恐,Retrofit支持Rxjava的結(jié)合使用液斜,可以在獲取網(wǎng)絡(luò)數(shù)據(jù)或者數(shù)據(jù)庫等數(shù)據(jù)之后利用Rxjava對(duì)數(shù)據(jù)流進(jìn)行各種操作包括不僅限于數(shù)據(jù)流的合并,過濾叠穆,重新排序少漆,以及后續(xù)的數(shù)據(jù)庫存儲(chǔ)等一系列鏈?zhǔn)教幚砗蟾碌絍iew層
- EventBus 事件總線,可以避免回調(diào)地獄硼被,如果項(xiàng)目中到處都是接口回調(diào)示损,例如拿到數(shù)據(jù)后各種通過接口回調(diào)告知View更新界面,這對(duì)于后期維護(hù)是一件很可怕的事情嚷硫,常見的事件總線有otto,eventbus,Rxbus等框架
正題: greenDao的使用
過去使用原生的sqliteOpenHelper雖然靈活但是需要寫sql語句感覺還是有些繁瑣检访,于是嘗試使用orm框架來改進(jìn)始鱼,對(duì)比了下android上常用的orm框架,都說greenDao的性能脆贵,內(nèi)存等方面在android平臺(tái)都進(jìn)行過優(yōu)化医清,是比較被推薦使用的。但是相比LiteOrm這類基于注解的框架學(xué)習(xí)起來要麻煩一些丹禀。并不是簡(jiǎn)單的導(dǎo)入個(gè) compile 'xxx:1.0.0'就可以使用的状勤。下面就一步一步講解怎么使用鞋怀。小弟有說的不正確的地方双泪,大兄弟請(qǐng)見諒。 密似。
- 在app主項(xiàng)目的build.gradle的dependencies中添加 compile 'org.greenrobot:greendao:2.2.0'
2 .在project工程中新建一個(gè)model選擇java Library 類型焙矛,model命名為dao-example-generator,名字隨意残腌,此model的build.gradle的dependencies中添加 compile 'org.greenrobot:greendao-generator:2.2.0'
3 .dao-example-generator中新建一個(gè)Class村斟,copy以下代碼到此類中。
public class Daogenerator {
public static void main(String[] args) throws Exception {
Schema schema = new Schema(2, "com.ssp.greendao.dao");//1是數(shù)據(jù)庫版本號(hào)抛猫,com.ssp.greendao.dao是自動(dòng)生成的java類存放的包名蟆盹,包括核心的DaoMaster,DaoSession等
addNote(schema);
addCustomerOrder(schema);
addStudentCourse(schema);
new DaoGenerator().generateAll(schema, "./app/src/main/java");//DaoMaster,DaoSession等自動(dòng)生成java類存放在app Model的src/main/java文件夾下
}
/**
* 添加一張單表
*
* @param schema
*/
private static void addNote(Schema schema) {
Entity note = schema.addEntity("Note");//創(chuàng)建一張Note表
note.addIdProperty().primaryKey().autoincrement();//設(shè)置主鍵自增長(zhǎng)
// note.addIdProperty();這樣默認(rèn)就是id是主鍵并且自增長(zhǎng)了,如果要自己設(shè)置一個(gè)鍵作為主鍵可以按上面一行代碼這樣寫
note.addStringProperty("text").notNull();//增加String類型的text列并且不能是空的闺金,如果插入內(nèi)容是空的會(huì)報(bào)異常
note.addStringProperty("comment");
note.addDateProperty("date");
}
/**
* 添加兩張表顧客表和訂單表逾滥,一對(duì)多關(guān)系
*
* @param schema
*/
private static void addCustomerOrder(Schema schema) {
Entity customer = schema.addEntity("Customer");
customer.addIdProperty();//設(shè)置默認(rèn)的id主鍵
customer.addStringProperty("name").notNull();
Entity order = schema.addEntity("Order");
order.setTableName("ORDERS"); // "ORDER" is a reserved keyword ,設(shè)置表名
order.addIdProperty();
Property orderDate = order.addDateProperty("date").getProperty();
Property customerId = order.addLongProperty("customerId").notNull().getProperty();
// 外鍵添加,外鍵customerId
order.addToOne(customer, customerId);
ToMany customerToOrders = customer.addToMany(order, customerId);//1對(duì)多關(guān)系败匹,一個(gè)Customer顧客可以有多個(gè)Order訂單寨昙,一個(gè)Order訂單只屬于一個(gè)Customer顧客
customerToOrders.setName("orders");//設(shè)置Api的名稱 getOrders()
customerToOrders.orderAsc(orderDate);//設(shè)置查詢結(jié)果按時(shí)間進(jìn)行升序排序
}
/**
* 添加三張表學(xué)生表,課程表還有一張中間表掀亩,多對(duì)多關(guān)系
*
* @param schema
*/
private static void addStudentCourse(Schema schema) {
Entity student = schema.addEntity("Student");
student.addIdProperty();
student.addStringProperty("name").notNull();
student.addStringProperty("sex").notNull();
Entity course = schema.addEntity("Course");
course.addIdProperty();
course.addStringProperty("courseName").notNull();
Entity studentCourse = schema.addEntity("studentCourse");//中間表用于關(guān)聯(lián)學(xué)生表和課程表
Property studentId = studentCourse.addLongProperty("studentId").getProperty();
Property courseId = studentCourse.addLongProperty("courseId").getProperty();
studentCourse.addToOne(student, studentId);
studentCourse.addToOne(course, courseId);
student.addToMany(studentCourse, studentId);
course.addToMany(studentCourse, courseId);
}
}
代碼不在解釋了舔哪,注釋寫的很清楚了。槽棍。捉蚤。特殊其實(shí)就是這個(gè)類它可以幫助生成后面CRUD需要使用到的各種Dao
4 .運(yùn)行上面這個(gè)類稍等片刻會(huì)發(fā)現(xiàn)在app模塊中多出了一個(gè)包
并且該包下面有很多java文件,這就是上面第三步自動(dòng)生成的炼七,各種Dao
5 .上面已經(jīng)把環(huán)境弄好了外里,開始使用,greenDao建議我們把daoMaster特石,daoSession等放在Application中這樣可以避免反復(fù)創(chuàng)建session增加開銷
public class MyApplication extends Application {
private DaoMaster daoMaster;
private DaoSession daoSession;
public DaoMaster getDaoMaster() {
if (daoMaster == null) {
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "notes-db", null);//notes-db是創(chuàng)建的數(shù)據(jù)庫db名稱
SQLiteDatabase db = helper.getWritableDatabase();
daoMaster = new DaoMaster(db);
}
return daoMaster;
}
public DaoSession getDaoSession() {
if (daoSession == null) {
daoSession = getDaoMaster().newSession();
}
return daoSession;
}
}
簡(jiǎn)單的插入一條數(shù)據(jù)盅蝗,其他的也類似比較簡(jiǎn)單就不啰嗦了,如果項(xiàng)目中的CRUD比較復(fù)雜可以封裝到一個(gè)dbService中
Note note = new Note(null, noteText, comment, new Date());
NoteDao noteDao = mApplication.getDaoSession().getNoteDao();//獲取dao
noteDao.insert(note);//向note表插入一條數(shù)據(jù)