`
kevinffk
  • 浏览: 34785 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

【原创】Active Android的一些见解与研究

阅读更多
这几天一直在找一个针对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
分享到:
评论
1 楼 whawei 2014-04-23  
ActiveAndriodDemo 有工程源码吗?可否共享?

相关推荐

    使用Android studio 实现的 active fragment

    `Active Fragment`的概念可能是指一种具有动态行为或交互性的`Fragment`实现,通常与用户界面的某些活动部分相关,如底部导航栏(Bottom Bar)。 在Android Studio中,开发者经常使用`Fragment`来构建模块化的应用...

    基于Android平台的人脸识别研究

    ### 基于Android平台的人脸识别研究 #### 摘要解读与研究背景 人脸识别技术作为生物识别技术的一种,具备非接触性、安全性及便捷性的显著特点,在人机交互、在线交易验证以及智能安防等领域得到了广泛应用。由于其...

    安装Active Directory 安装Active Directory 安装Active Directory

    安装Active Directory 安装Active Directory 安装Active Directory

    ActivePerl-5_ActivePerl5.28_ActivePerl_源码.zip

    ActivePerl包括了完整的Perl解释器和标准库,还额外提供了一些实用工具,如PPM(Perl Package Manager)用于安装和管理第三方模块。 三、ActivePerl 5.28的新特性 ActivePerl 5.28基于Perl 5.28,这个版本引入了...

    active教程与讲解

    《active教程与讲解》 在IT领域,"active"一词常常被用于各种上下文中,如活动状态、主动组件或动态交互。在这个教程中,我们将深入探讨与"active"相关的概念,尤其是它在软件安装、更新和管理中的应用。通过学习本...

    ActivePerl-5.14.0.1400

    标签“ActivePerl_5.14.”强调了这与Perl 5.14系列相关,这是一个中期版本,发布于2012年,包含了对语言的许多增强和新功能,比如增加了新的数据类型,改进了错误处理机制,以及对模块管理和编码标准的更新。...

    ActivePerl-5_ActivePerl5.28_ActivePerl.zip

    总的来说,ActivePerl-5.28为Windows用户提供了强大的Perl开发环境,使他们能够利用Perl的强大功能进行编程,同时享受与Windows平台兼容的便利性。无论是新手还是经验丰富的Perl开发者,都能从这个精心打包的发行版...

    ActivePerl_5.16

    ActivePerl的一个主要优点是它与Windows环境的无缝集成,提供了许多Windows特定的功能,如注册表集成、批处理文件支持和命令行工具。此外,它还包含一个CPAN(Comprehensive Perl Archive Network)客户端,方便用户...

    Vue实现active点击切换方法

    @click=active(index) 2、将索引值传入class(索引等于几就第几个添加active类) :class={active:index==ins} 3、在data里边添加ins:0(表示默认第一个添加active类) data{ ins:0 } 4、最后在methods里边添加...

    ActiiveAndroidDemo:演示如何使用Active Android ORM的示例代码

    **Active Android ORM 深度解析** Active Android 是一个开源的对象关系映射(ORM)库,专门为简化Android应用中的数据库操作而设计。它允许开发者使用Java对象来操作数据库,而无需编写大量的SQL语句,提高了开发...

    Android中获取正在运行的服

    在Android系统中,服务(Service)是一种用于在后台执行长时间操作的应用组件,它们不与用户交互,但可以被其他组件启动或绑定。了解如何获取正在运行的服务对于开发者来说至关重要,特别是进行性能分析、调试或者...

    ActivePerl 安装包

    一旦安装完毕,ActivePerl将提供一个完整的Perl环境,包括Perl解释器、核心模块和一些常用的第三方模块。用户可以通过命令行或者集成开发环境(IDE)来编写和运行Perl脚本。ActivePerl还支持CPAN(Comprehensive Perl ...

    ​ActivePerl5.28版本下载、ActivePerl下载

    ​ActivePerl是一个perl脚本解释器。其包含了包括有 Perl for Win32、Perl for ISAPI、PerlScript、Perl Package Manager四套开发工具程序,可以让用户编写出适用于unix,windows,linux系统的CGI程序来。 CGI...

    ActiveReport初学启示

    初学者在学习ActiveReport时,可能会遇到一些挑战,比如如何设置报表布局,添加数据源,以及如何自定义样式等。以下是一些关键的知识点,旨在帮助初学者快速上手: 1. **安装与集成**:首先,你需要下载并安装...

    ActiveReport报表控件

    这个压缩包中包含了与ActiveReport相关的源代码和教程,以及一些使用水晶报表(Crystal Reports)的示例,让我们逐一解析这些资源。 1. **Asp.Net中使用水晶报表 - goody9807 - 博客园.htm**:这是一个关于如何在...

    ActivePerl.zip

    在Windows环境中,ActivePerl提供了与Unix/Linux平台类似的Perl环境,支持大部分Perl模块,使得开发人员能够在跨平台项目中保持一致性。 压缩文件中的"ActivePerl-5.20.2MSWin32.msi"是ActivePerl的安装程序,版本...

    ActivePerl-5.10

    在安装ActivePerl后,用户可以利用Perl的强大功能,如正则表达式、模块化编程、文本处理以及与系统交互的能力。此外,Perl拥有丰富的第三方模块库CPAN(Comprehensive Perl Archive Network),可以方便地扩展其功能...

    activescript 3.0 类库 帮助手册

    8. **示例和案例研究**:手册中必定包含大量示例代码,展示如何在实际项目中应用ActiveScript 3.0的各种功能。这些示例涵盖了从简单任务到复杂应用的各种场景。 9. **API参考**:详尽的API参考文档,列出了所有的...

    ActiveReport报表使用案例

    通过深入研究这个"Demo",开发者不仅可以掌握ActiveReport的基本用法,还能了解到高级特性,如分页报表、交互式仪表盘、数据钻取和分析等。这将极大地提升他们在项目中创建复杂报表的能力,提高工作效率。

Global site tag (gtag.js) - Google Analytics