最近想了解一下关于Android ORM的东西,在网上一搜,框架还真不少,很多人都说GreenDao性能不错,这周末就好好搞了下。
现在Goodle推出了Android studio这款开发利器,是用Gradle构建,感觉还不错。以下项目都是用Android studio 0.8.14开发。
具体build.gradle请参照给出代码。因为是首次使用,所以开发中遇过不少问题,我会在最后跟大家分享一下。
测试代码是直接拿的人家的,https://github.com/greenrobot/greenDAO,因为版本问题直接用不行,所以代码我有改动。
Step1:创建Project-GreenDao
同时默认创建Module app,创建时可以不生成Activity。
Step2:创建一个普通Java工程
在Project-GreenDao下创建一个Module,类型选择Java library。此处我创建的是dao-example-generator。
在该Module下新建一个类ExampleDaoGenerator,源码如下:
package com.ssp.greendao.generator;
import de.greenrobot.daogenerator.DaoGenerator;
import de.greenrobot.daogenerator.Entity;
import de.greenrobot.daogenerator.Property;
import de.greenrobot.daogenerator.Schema;
import de.greenrobot.daogenerator.ToMany;
public class ExampleDaoGenerator {
public static void main(String[] args) throws Exception {
Schema schema = new Schema(1, "com.ssp.greendao.dao");
addNote(schema);
addCustomerOrder(schema);
new DaoGenerator().generateAll(schema, "./app/src/main/java");
}
private static void addNote(Schema schema) {
Entity note = schema.addEntity("Note");
note.addIdProperty();
note.addStringProperty("text").notNull();
note.addStringProperty("comment");
note.addDateProperty("date");
}
private static void addCustomerOrder(Schema schema) {
Entity customer = schema.addEntity("Customer");
customer.addIdProperty();
customer.addStringProperty("name").notNull();
Entity order = schema.addEntity("Order");
order.setTableName("ORDERS"); // "ORDER" is a reserved keyword
order.addIdProperty();
Property orderDate = order.addDateProperty("date").getProperty();
Property customerId = order.addLongProperty("customerId").notNull().getProperty();
order.addToOne(customer, customerId);
ToMany customerToOrders = customer.addToMany(order, customerId);
customerToOrders.setName("orders");
customerToOrders.orderAsc(orderDate);
}
}
build.gradle内容如下:
apply plugin: 'java'
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile 'de.greenrobot:greendao-generator:1.3.1'
}
sourceSets {
main {
java {
srcDir 'src/main/java'
}
}
}
artifacts {
archives jar
}
运行类ExampleDaoGenerator,会在app/src/main/java目录下生成greendao创建的文件。为什么会在Module app java源文件下生成呢?这是因为在类中有一行代码:
new DaoGenerator().generateAll(schema, "./app/src/main/java");
Step3:在app中创建NoteActivity测试
NoteActivity代码如下:
package com.ssp.greendao;
import android.app.ListActivity;
import android.app.LoaderManager;
import android.content.Context;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import com.ssp.greendao.dao.DaoMaster;
import com.ssp.greendao.dao.DaoSession;
import com.ssp.greendao.dao.Note;
import com.ssp.greendao.dao.NoteDao;
import java.text.DateFormat;
import java.util.Date;
public class NoteActivity extends ListActivity {
private static SQLiteDatabase db;
private EditText editText;
private DaoMaster daoMaster;
private DaoSession daoSession;
private static NoteDao noteDao;
private Cursor cursor;
private SimpleCursorAdapter adapter;
private MyCursorLoader my;
private LoaderManager manager;
public static class MyCursorLoader extends CursorLoader{
public MyCursorLoader(Context context) {
super(context);
}
public Cursor loadInBackground(){
return db.query(noteDao.getTablename(),noteDao.getAllColumns(), null, null, null, null, null);
}
}
public LoaderManager.LoaderCallbacks<Cursor> callbacks = new LoaderManager.LoaderCallbacks<Cursor>() {
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new MyCursorLoader(getApplicationContext());
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
String textColumn = NoteDao.Properties.Text.columnName;
String[] from = { textColumn, NoteDao.Properties.Comment.columnName };
int[] to = { android.R.id.text1, android.R.id.text2 };
adapter = new SimpleCursorAdapter(getApplicationContext(), android.R.layout.simple_list_item_2, cursor, from,
to, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
setListAdapter(adapter);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note);
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "notes-db", null);
db = helper.getWritableDatabase();
daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession();
noteDao = daoSession.getNoteDao();
manager = getLoaderManager();
manager.initLoader(1,null,callbacks);
editText = (EditText) findViewById(R.id.editTextNote);
addUiListeners();
}
protected void addUiListeners() {
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;
}
});
final View button = findViewById(R.id.buttonAdd);
button.setEnabled(false);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
boolean enable = s.length() != 0;
button.setEnabled(enable);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
public void onMyButtonClick(View view) {
addNote();
}
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());
noteDao.insert(note);
Log.d("DaoExample", "Inserted new note, ID: " + note.getId());
//cursor.requery();
//cursor = my.loadInBackground();
manager.restartLoader(1,null,callbacks);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
noteDao.deleteByKey(id);
Log.d("DaoExample", "Deleted note, ID: " + id);
//cursor.requery();
//cursor = my.loadInBackground();
manager.restartLoader(1,null,callbacks);
}
}
此类主要是用greendao生成的类来演示对Note表的操作。
layout/activity_note.xml内容如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/linearLayout1"
android:orientation="horizontal">
<EditText
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_width="wrap_content"
android:inputType="text"
android:imeOptions="actionDone"
android:id="@+id/editTextNote"
android:hint="Enter new note"></EditText>
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Add"
android:id="@+id/buttonAdd"
android:onClick="onMyButtonClick"></Button>
</LinearLayout>
<ListView
android:layout_height="wrap_content"
android:id="@android:id/list"
android:layout_width="fill_parent"></ListView>
</LinearLayout>
build.gradle内容如下:
apply plugin: 'com.android.application'
android {
compileSdkVersion 20
buildToolsVersion "20.0.0"
defaultConfig {
applicationId "com.ssp.greendao"
minSdkVersion 15
targetSdkVersion 20
versionCode 1
versionName "1.0"
}
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6
targetCompatibility JavaVersion.VERSION_1_7
}
dexOptions {
incremental true
}
}
dependencies {
//classpath 'com.android.tools.build:gradle:0.13.2'
compile('de.greenrobot:greendao:1.3.0') {
exclude module: 'support-v4'
exclude module: 'junit'
exclude module: 'android-test'
exclude module: 'annotations'
exclude module: 'android'
}
//compile 'com.android.support:support-v4:20.0.+'
compile 'com.android.support:appcompat-v7:20.0.+'
}
sourceSets {
main {
java {
srcDir 'src/main/java'
}
}
}
如果以上几步都已成功构建,运行app就可以操作了。效果图如下:
问题及使用注意点:
- File->Settings->Gradle->Project-level-settings ,我选择了Use default gradle wrapper(recommended),好处官网上好像有解释
- Project根下的build.gradle里,我在依赖里添加了classpath 'com.android.tools.build:gradle:0.13.2',注意gradle/wrapper/gradle-wrapper.properties内容
如果出现了gradle类的问题,可以在网上查找一下Android Studio、Android Gradle Plugin、Gradle之间的版本对应。
- 依赖包引入多次的问题,可以在终端用命令查看依赖关系:gradlew -q dependencies。使用方法可以参照我上面的配置。
- 编译运行时出现一些莫名其妙的问题,可以试试先clean->Snyc Project with Gradle Files->run。
本人只是刚入门Android,上述纯属个人使用过程中发现,有些地方请不要硬套,很多都是版本兼容问题。GreenDao再深入的没有搞,其它的ORM现在也没时间看。