这几天一直在找一个针对android数据库sqlite的一个orm框架,起初找了一个google上面的项目:android active record,无奈,demo可以运行,但自己写了一个应用,却怎么也跑不起来,原因是创建DB的sql语句有错误。于是debug了一番,然后发现错误不仅仅是这些。要我改原作者的代码是不可能的,更何况他的代码还没有完善与健壮。尔后几天一直在找有没有相应的框架可替代。找了个ormlite和sqlitegen,都不竟如人意,并不是说它们的框架设计得不合理,而是就简约和敏捷开发而言。orm的缺点就暴露了出来,令外,手机软件一般追求的是代码简洁,而J2EE的这一套显然在这里无法适用。终于,被我找到了一个商业版的active android。思想跟我找到那个google项目一样,都是基于RoR的activeRecord模式设计的。我下了一个试用版(正式版可要付$19.99 T_T)。再反编译一下,天,居然没有代码混淆。于是,看了下代码的实现。研究了大概1天半的时间。它的实例也跑过了,再把它应用于自己的小例子中,终于,跨过重重的困难。勉强OK了。但这里有个问题摆在眼前,试用版的,一些功能会有限制,果然,在它代码里面,我看到了它仅限于运行在模拟器。而且生成的DB名字不可变更。DB命名的那段逻辑在它自己实现的application上面call。且这些代码封装在它的jar包里面。这样就意味着application的命名要跟jar包里面的一致,否则无法应用。看来,要改它的代码是必然的,不然这些限制将不利于自己的应用(在这里,希望一些版权人士不要喷我,小弟只是抱着学习的态度去研究这框架,并未用于商业的开发)。于是,经过昨天的熬夜奋战,终于解决了这一问题,改了它的实现接口,在应用端方法只需写一个类继承那个jar包的application就可以了。另外,运行于真机器也没问题。好了,不多说了,上一个我的小例子ActiveAndriodDemo,方便大家理解。
1.AndroidManifest.xml上面的改动。
<application android:icon="@drawable/icon" android:label="@string/app_name" android:name="com.kevin.PersonApp">
...</application>
2.创建一个跟上面命名一样的PersonApp类,并继承activeAndroid.jar下面的applicatiion类。
package com.kevin;
import com.activeandroid.Application;
public class PersonApp extends Application {
public PersonApp() {
//naming DB name and DB version
super("PersonApp.db", 1);
}
}
3.domain类(Person.java)
package com.kevin.entity;
import java.util.List;
import android.content.Context;
import com.activeandroid.ActiveRecordBase;
import com.activeandroid.annotation.Column;
import com.activeandroid.annotation.Table;
@Table(name = "Person") //naming table name
public class Person extends ActiveRecordBase<Person>{
public Person(Context context) {
super(context);
}
//naming column name, just ignore length value setting
@Column(name = "Name")
public String name;
@Column(name = "age")
public String age;
public static List<Person> getAll(Context context) {
return Person.query(context, Person.class, null, null, null);
}
}
4.创建一个适配器PeopleAdapter.java
package com.kevin.adapter;
import java.util.ArrayList;
import java.util.List;
import com.kevin.R;
import com.kevin.entity.Person;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class PeopleAdapter extends BaseAdapter {
private LayoutInflater layoutInflater;
private List<Person> people = new ArrayList<Person>();
public PeopleAdapter(Context context, List<Person> personList) {
layoutInflater = LayoutInflater.from(context);
people.addAll(personList);
}
@Override
public int getCount() {
return people.size();
}
@Override
public Object getItem(int position) {
return people.get(position);
}
@Override
public long getItemId(int position) {
return people.get(position).getId();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
Person person = (Person) getItem(position);
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.list_item, null);
holder.id = (TextView) convertView.findViewById(R.id.p_id);
holder.name = (TextView) convertView.findViewById(R.id.p_name);
holder.age = (TextView) convertView.findViewById(R.id.p_age);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.id.setText(person.getId() + "");
holder.name.setText(person.name);
holder.age.setText(person.age);
return convertView;
}
class ViewHolder{
TextView id;
TextView name;
TextView age;
}
}
5.Main.java主activity
package com.kevin;
import java.util.List;
import com.kevin.adapter.PeopleAdapter;
import com.kevin.entity.Person;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.AdapterView.AdapterContextMenuInfo;
public class Main extends ListActivity {
private PeopleAdapter peopleAdapter;
private static final int EDIT_DIALOG = 1;
private static final int ADD_MENU = 0;
private EditText editName;
private EditText editAge;
private Person person;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadList();
registerForContextMenu(getListView());
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.item_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.edit: {
editPerson(info.id);
return true;
}
case R.id.delete: {
deletePerson(info.id);
return true;
}
default:
return super.onContextItemSelected(item);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, ADD_MENU, 0, "Add Person");
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch (item.getItemId()) {
case ADD_MENU:
addPerson();
return true;
default:
return super.onMenuItemSelected(featureId, item);
}
}
@Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case EDIT_DIALOG: {
LayoutInflater inflater = LayoutInflater.from(this);
View textEntryView = inflater.inflate(R.layout.alert_dialog, null);
editName = (EditText) textEntryView.findViewById(R.id.name);
editAge = (EditText) textEntryView.findViewById(R.id.age);
AlertDialog.Builder builder = new AlertDialog.Builder(Main.this);
builder.setView(textEntryView);
String title = "Add Person";
if (person != null) {
title = "Edit Person";
editName.setText(person.name);
editAge.setText(person.age);
}
builder.setTitle(title);
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String name = editName.getText().toString();
String age = editAge.getText().toString();
if(person == null) {
person = new Person(Main.this);
}
person.name = name;
person.age = age;
person.save();
loadList();
removeDialog(EDIT_DIALOG);
}
});
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
removeDialog(EDIT_DIALOG);
}
});
return builder.create();
}
default:
return super.onCreateDialog(id);
}
}
private void loadList() {
List<Person> personList = Person.getAll(this);
peopleAdapter = new PeopleAdapter(this, personList);
setListAdapter(peopleAdapter);
}
private void editPerson(long id) {
person = Person.load(this, Person.class, id);
showDialog(EDIT_DIALOG);
}
private void deletePerson(long id) {
Person.delete(this, Person.class, id);
loadList();
}
private void addPerson() {
person = null;
showDialog(EDIT_DIALOG);
}
}
由于例子较长,部分代码(渲染界面和menu)忽略。
在这里总结一下ActiveAndroid。
优点: 方便,不用写sql,领域驱动模式可以使CRUD封装到domain上面,还可以扩展条件查询,支持简单的外键功能。
缺点: 每个表都默认有Id字段,并且是自增长,不可以自定义主键。不适应于小项目,性能较差。annotation的信息较小,生成的DDL十分的笼统。
修改:可以应用于真机器上面。可自定义数据库名或版本名,并且可自定义application name。
还有个小技巧可以教大家:
android 项目引入lib
1.在project上面添加"libs"
2.将library copy到libs下面
3.将library右键添加入项目
这样,lib会随着project一起安装。
- 大小: 15.4 KB
- 大小: 7.2 KB
- 大小: 8 KB
分享到:
相关推荐
使用Android studio实现 active fragment,实现了bottom bar, 有四个button,分别连接到四个不同页面
安装Active Directory 安装Active Directory 安装Active Directory
@click=active(index) 2、将索引值传入class(索引等于几就第几个添加active类) :class={active:index==ins} 3、在data里边添加ins:0(表示默认第一个添加active类) data{ ins:0 } 4、最后在methods里边添加...
详细教述active教程与使用方法 目录 附件
ActivePerl-5_ActivePerl5.28_ActivePerl.zip
压缩包中包含Client Android 端和Service 端,Service端采用apache-activemq-5.13.3最新的版本。Android端采用MQTT实现了消息的接收,接收消息的回调是messageArrived方法。 Server端的简要使用说明如下: 1、解压...
ActivePerl-5.28.1 win10 x64离线安装包(官方),可避免从官网下载速度慢的问题。 ActivePerl-5.28.1 win10 x64离线安装包(官方),可避免从官网下载速度慢的问题。 ActivePerl-5.28.1 win10 x64离线安装包(官方...
ActivePerl-5_ActivePerl5.28_ActivePerl_源码.zip
Active contours without edge 数字图像处理 MRI 无边缘动态轮廓
Active Object技术讲解
活动形状模型(Active Shape Models)与活动轮廓模型(Active Contour Models)的MATLAB实现。
Active Directory access
可以在使用注册表参数 DsCacheRefreshSecs 刷新缓存中与匿名用户对应的 Active Directory 属性之前,限制最大运行时间。 要点 要在 Active Directory 模式下将 FTP 用户隔离用于 Windows 2000 域控制器,您需要在 ...
但域对初学者来说显得复杂了一些,众多的技术术语,例如Active Directory,站点,组策略,复制拓扑,操作主机角色,全局编录….很多初学者容易陷入这些技术细节而缺少了对全局的把握。从今天开始,我们将推出Active ...
ActiveMessenger Show IP Plugins 显示客户端IP地址插件
No longer in active development NTPSync is no longer in active development. If you like to take over the maintaining, simply fork it and implement fixes. I will only do basic maintenance like merging ...
Active Directory教程 基本全面的Active Directory系列
DNS 服务器无法打开 Active Directory
idea安装后续active
c#创建active控件