Skip to content

Latest commit

 

History

History
executable file
·
328 lines (215 loc) · 7.54 KB

File metadata and controls

executable file
·
328 lines (215 loc) · 7.54 KB

##ActiveAndroid使用与源码分析

ActiveAndroid是采用活动记录(Active Record)架构模式设计的适用于Android平台的轻量级ORM架构。

1.配置与初始化

首先在AndroidManifest.xml文件中配置数据库名称和数据库版本号。

<manifest ...>
    <application android:name="com.activeandroid.app.Application" ...>

        ...

        <meta-data android:name="AA_DB_NAME" android:value="Pickrand.db" />
        <meta-data android:name="AA_DB_VERSION" android:value="5" />
    </application>
</manifest>
  • AA_DB_NAME:数据库名
  • AA_DB_VERSION:数据库版本号,默认是1。

接着,在AndroidManifest.xml文件中指定application元素的name为com.activeandroid.app.Application,如果需要自定义Application,需要让你的Application对象继承自com.activeandroid.app.Application而不是android.app.Application。如果你需要继承其他库的Application,则需要在Application中初始化和处理ActiveAndroid。

public class MyApplication extends SomeLibraryApplication {
    @Override
    public void onCreate() {
        super.onCreate();
        ActiveAndroid.initialize(this);
    }
    @Override
    public void onTerminate() {
        super.onTerminate();
        ActiveAndroid.dispose();
    }
}

2.创建Model

创建数据库模型非常简单,创建的模型必须继承Model类,这样你的类名就是你的表名。如果不想使用类名做表名,则可以使用@Table定义表名。@Column用于定义列名。Model类使用无参的构造函数,如果定义自己的构造函数必须定义一个无参的构造函数。

@Table(name = "Categories")
public class Category extends Model {
    @Column(name = "Name")
    public String name;
}

@Table(name = "Items")
public class Item extends Model {
    @Column(name = "remote_id", unique = true, onUniqueConflict = Column.ConflictAction.REPLACE)
    public int remoteId;
    @Column(name = "Name")
    public String name;

    @Column(name = "Category")
    public Category category;

        public Item(){
                super();
        }
        public Item(String name, Category category){
                super();
                this.name = name;
                this.category = category;
        }
}

3.增删改查

3.1 插入

3.1.1 单条插入

保存一条记录,只需要创建一个模型的实例,并为每个字段指定值,然后调用save()方法。

Category restaurants = new Category();
restaurants.name = "Restaurants";
restaurants.save();

3.1.2批量插入

ActiveAndroid.beginTransaction();
try {
        for (int i = 0; i < 100; i++) {
            Item item = new Item();
            item.name = "Example " + i;
            item.save();
        }
        ActiveAndroid.setTransactionSuccessful();
}
finally {
        ActiveAndroid.endTransaction();
}

3.2 更新

new Update(Person.class).set("age=?," + "name=?", age, name).execute();

3.3 删除

调用delete()方法就可以删除一条记录,下面的例子中,通过id加载一个Item对象,并且删除他。

Item item = Item.load(Item.class, 1);
item.delete();

也可以通过静态方法删除

Item.delete(Item.class, 1);

也可以创建调用Delete对象删除

new Delete().from(Item.class).where("Id = ?", 1).execute();

3.4 查询

查询一条

public static Item getRandom(Category category) {
    return new Select()
        .from(Item.class)
        .where("Category = ?", category.getId())
        .orderBy("RANDOM()")
        .executeSingle();
}

查询所有

public static List<Item> getAll(Category category) {
    return new Select()
        .from(Item.class)
        .where("Category = ?", category.getId())
        .orderBy("Name ASC")
        .execute();
}

4. 使用内容提供者

使用ActiveAndroid的ContentProvider,必须复写默认的标识列如下所示(默认标识列是ID)。

@Table(name = "Items", id = BaseColumns._ID)
public class Item extends Model {...}

接着就可以使用ContentProvider

   mySpinner.setAdapter(new SimpleCursorAdapter(getActivity(),
        android.R.layout.simple_expandable_list_item_1,
        null,
        new String[] { "MyProperty" },
        new int[] { android.R.id.text1 },
        0));

    getActivity().getSupportLoaderManager().initLoader(0, null, new LoaderCallbacks<Cursor>() {
        @Override
        public Loader<Cursor> onCreateLoader(int arg0, Bundle cursor) {
            return new CursorLoader(getActivity(),
                ContentProvider.createUri(MyEntityClass.class, null),
                null, null, null, null
            );
        }

        @Override
        public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {
            ((SimpleCursorAdapter)mySpinner.getAdapter()).swapCursor(cursor);
        }

        @Override
        public void onLoaderReset(Loader<Cursor> arg0) {
            ((SimpleCursorAdapter)mySpinner.getAdapter()).swapCursor(null);
        }
    });

最后别忘了在AndroidManifest.xml中注册provider

<application ...>
    <provider android:authorities="com.example" android:exported="false" android:name="com.activeandroid.content.ContentProvider" />
    ...
</application>

源码分析

###程序初始化

程序入口是ActiveAndroid类的initialze方法

	public static void initialize(Configuration configuration, boolean loggingEnabled) {
		// Set logging enabled first
		setLoggingEnabled(loggingEnabled);
		Cache.initialize(configuration);
	}

初始化过程创建了一个 Configuration,并将Configuration传递给Cache进行初始化。

Configuration类主要从项目的清单文件中获取数据库名字和版本等相关信息。

在Cache的initialize方法中创建了一个ModelInfo对象和一个DatabaseHelper对象。

public static synchronized void initialize(Configuration configuration) {
...
		sContext = configuration.getContext();
		sModelInfo = new ModelInfo(configuration);
		sDatabaseHelper = new DatabaseHelper(configuration);
 ...
	}

ModelInfo 类通过scanForModel扫描应用程序的源码,获得所有Model的子类,并且获取这些Model的TableInfo,存储在map集合mTableInfos中。

TableInfo类通过反射获取类名和列名。

###创建表 DatabaseHelper中的executeCreate()方法进行创建数据库。

private void executeCreate(SQLiteDatabase db) {
		db.beginTransaction();
		try {
			for (TableInfo tableInfo : Cache.getTableInfos()) {
				db.execSQL(SQLiteUtils.createTableDefinition(tableInfo));
			}
			db.setTransactionSuccessful();
		}
		finally {
			db.endTransaction();
		}
	}
//改方法创建建表的数据库
	public static String createTableDefinition(TableInfo tableInfo) {
		final ArrayList<String> definitions = new ArrayList<String>();

		for (Field field : tableInfo.getFields()) {
		//创建列定义的语法
			String definition = createColumnDefinition(tableInfo, field);
			if (!TextUtils.isEmpty(definition)) {
				definitions.add(definition);
			}
		}

		definitions.addAll(createUniqueDefinition(tableInfo));

		return String.format("CREATE TABLE IF NOT EXISTS %s (%s);", tableInfo.getTableName(),
				TextUtils.join(", ", definitions));
	}

参考

https://github.com/thecodepath/android_guides/wiki/ActiveAndroid-Guide

https://github.com/pardom/ActiveAndroid