- 浏览: 259732 次
- 性别:
- 来自: 太原
-
最新评论
-
kinglo:
请问生成的文件怎么看?
Android 全局异常处理 -
yong7356:
学习一下。。。。。
Android Ant -
bzlring:
很好
Android 全局异常处理 -
M985300651:
難得一見的好教學
Android 自定义滚动视图 -
i5suoi:
thank you very much
Android 全局异常处理
SQLite数据库的CRUD
DBActivity
package org.wp.db; /** * 嵌入式关系型数据库 * SQLite * SQLite最大的特点是你可以保存任何类型的数据到任何字段中,无论这列声明的数据类型是什么 * 但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数 * 当向这种字段中保存除整数以外的数据时,将会产生错误 * 另外, SQLite 在解析CREATE TABLE 语句时,会忽略 CREATE TABLE 语句中跟在字段名后面的数据类型信息 * * SQLite可以解析大部分标准SQL语句,如: * 查询语句:select * from 表名 where 条件子句 group by 分组字句 having ... order by 排序子句 * 分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录 * select * from Account limit 5 offset 3 或者 select * from Account limit 3,5 * 插入语句:insert into 表名(字段列表) values(值列表) * 更新语句:update 表名 set 字段名 = 值 where 条件子句 * 删除语句:delete from 表名 where 条件子句 * */ import org.wp.service.DataBaseOpenHelper; import android.app.Activity; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; public class DBActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); /** * 第一次调用getWritableDatabase()或getReadableDatabase()方法后 * SQLiteOpenHelper会缓存当前的SQLiteDatabase实例 * SQLiteDatabase实例正常情况下会维持数据库的打开状态 * 所以在你不再需要SQLiteDatabase实例时 * 请及时调用close()方法释放资源 ,一旦SQLiteDatabase实例被缓存 * 多次调用getWritableDatabase()或getReadableDatabase()方法得到的都是同一实例 */ DataBaseOpenHelper dataBaseOpenHelper = new DataBaseOpenHelper( DBActivity.this); SQLiteDatabase database = dataBaseOpenHelper.getWritableDatabase(); database.execSQL("insert into person(name, age) values(?,?)", new Object[] { "张三", 9 }); database.close(); } }
DataBaseOpenHelper
package org.wp.service; /** * 在Android系统,为我们提供了一个名为SQLiteOpenHelper的类 * 该类用于对数据库版本进行管理,该类是一个抽象类,必须继承它才能使用 * 为了实现对数据库版本进行管理,SQLiteOpenHelper类有两种重要的方法 * 分别是onCreate(SQLiteDatabase db) 和 onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) * * 当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法 * 获取用于操作数据库的SQLiteDatabase实例的时候 * 如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()方法 * onCreate()方法在初次生成数据库时才会被调用 * 在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据 * onUpgrade()方法在数据库的版本发生变化时会被调用,数据库的版本是由程序员控制的 * 假设数据库现在的版本是1,由于业务的需要,修改了数据库表的结构,这时候就需要升级软件 * 升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为2 * 并且在onUpgrade()方法里面实现表结构的更新 * 当软件的版本升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断 * 然后作出相应的表结构及数据更新 * * getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例 * 但getWritableDatabase()方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写 * 倘若使用的是getWritableDatabase()方法就会出错 * * getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败 * 当打开失败后会继续尝试以只读方式打开数据库 * */ import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DataBaseOpenHelper extends SQLiteOpenHelper { // 类没有实例化,是不能用作父类构造器的参数,必须声明为静态 private static final String DBNAME = "wp";// 数据库名称 private static final int VERSION = 1;// 数据库版本 public DataBaseOpenHelper(Context context) { // 第三个参数CursorFactory指定在执行查询时获得一个游标实例的工厂类,设置为null,代表使用系统默认的工厂类 super(context, DBNAME, null, VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("create table person(personid integer primary key autoincrement,name varchar(20),age integer)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("drop table if exists person"); onCreate(db); } }
PersonService
package org.wp.service; /** * Android 提供了一个名为SQLiteDatabase的类 * 该类封装了一些操作数据库的API,使用该类可以完成对数据CRUD操作 */ import java.util.ArrayList; import java.util.List; import org.wp.domain.Person; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; public class PersonService { private DataBaseOpenHelper dataBaseOpenHelper; private SQLiteDatabase database; public PersonService(Context context) { dataBaseOpenHelper = new DataBaseOpenHelper(context); } public void save(Person person) { database = dataBaseOpenHelper.getWritableDatabase(); database.execSQL("insert into person(name,age) values(?,?)", new Object[] { person.getName(), person.getAge() }); // database.close(); } /** * Java1.5 增加了新特性 可变参数 适用于参数个数不确定,类型确定的情况,Java把可变参数当做数组处理。 * * @param ids */ public void delete(Integer... ids) { if (ids.length > 0) { StringBuilder sb = new StringBuilder(); for (Integer id : ids) { sb.append('?').append(','); } sb.deleteCharAt(sb.length() - 1); database = dataBaseOpenHelper.getWritableDatabase(); database.execSQL( "delete from person where personid in(" + sb + ")", (Object[]) ids); } } public void update(Person person) { database = dataBaseOpenHelper.getWritableDatabase(); database.execSQL("update person set name=?,age=? where personid=?", new Object[] { person.getName(), person.getAge(), person.getPersonid() }); } public Person find(Integer id) { database = dataBaseOpenHelper.getReadableDatabase(); /** * Cursor是结果集游标,用于对结果集进行随机访问 使用moveToNext()方法可以将游标从当前行移动到下一行 * 如果已经移过了结果集的最后一行,返回结果为false,否则为true * 另外Cursor 还有常用的 * moveToPrevious()方法 * 用于将游标从当前行移动到上一行,如果已经移过了结果集的第一行,返回值为false,否则为true * moveToFirst()方法 * 用于将游标移动到结果集的第一行,如果结果集为空,返回值为false,否则为true * moveToLast()方法 * 用于将游标移动到结果集的最后一行,如果结果集为空,返回值为false,否则为true */ Cursor cursor = database.rawQuery( "select * from person where personid=?", new String[] { String .valueOf(id) }); if (cursor.moveToNext()) { return new Person(cursor.getInt(0), cursor.getString(1), cursor .getShort(2)); } return null; } /** * * SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset * LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数 * LIMIT 接受一个或两个数字参数。参数必须是一个整数常量 * 如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目 * 初始记录行的偏移量是 0(而不是 1): * SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15 * 为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1 * SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last. * 如果只给定一个参数,它表示返回最大的记录行数目: * SELECT * FROM table LIMIT 5; //检索前 5 个记录行 * 换句话说,LIMIT n 等价于 LIMIT 0,n。 * */ public List<Person> getScrollData(int startResult, int maxResult) { List<Person> persons = new ArrayList<Person>(); database = dataBaseOpenHelper.getWritableDatabase(); Cursor cursor = database.rawQuery("select * from person limit ?,?", new String[] { String.valueOf(startResult), String.valueOf(maxResult) }); while (cursor.moveToNext()) { persons.add(new Person(cursor.getInt(0), cursor.getString(1), cursor.getShort(2))); } return persons; } public long getCount() { database = dataBaseOpenHelper.getReadableDatabase(); Cursor cursor = database.rawQuery("select count(*) from person ", null); while (cursor.moveToNext()) { return cursor.getLong(0); } return 0; } }
OtherPersonService
package org.wp.service; /** * Insert()方法用于添加数据,各个字段的数据使用ContentValues进行存放 * ContentValues类似于MAP,相对于MAP,它提供了存取数据对应的 * put(String key, Xxx value)和getAsXxx(String key)方法 * key为字段名称,value为字段值,Xxx指的是各种常用的数据类型 * 如:String、Integer等 * long rowid = db.insert("person", null, values);//返回新添记录的行号,与主键id无关 * */ import java.util.ArrayList; import java.util.List; import org.wp.domain.Person; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; public class OtherPersonService { private DataBaseOpenHelper dataBaseOpenHelper; private SQLiteDatabase database; public OtherPersonService(Context context) { dataBaseOpenHelper = new DataBaseOpenHelper(context); } /** * * database.insert(table, nullColumnHack, values); * 不管第三个参数是否包含数据,执行Insert()方法必然会添加一条记录 * 如果第三个参数为空,会添加一条除主键之外其他字段值为Null的记录 * Insert()方法内部实际上通过构造insert语句完成数据的添加 * Insert()方法的第二个参数用于指定空值字段的名称 * 如果第三个参数values为Null或者元素个数为0 * Insert()方法必然要添加一条除了主键之外其它字段为Null值的记录 * 为了满足这条insert语句的语法,insert语句必须给定一个字段名 如:insert into person(name) values(NULL) * 倘若不给定字段名 ,insert语句就成了这样: insert into person() values() * 显然这不满足标准SQL的语法。对于字段名,建议使用主键之外的字段 * 如果使用了INTEGER类型的主键字段,执行类似insert into person(personid) values(NULL)的insert语句后该主键字段值也不会为NULL * 如果第三个参数values不为Null并且元素的个数大于0 ,可以把第二个参数设置为null * * @param person */ public void save(Person person) { database = dataBaseOpenHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("name", person.getName()); values.put("age", person.getAge()); // 必须添加记录,除了主键之外,其他字段的值都为NULL database.insert("person", "name", values); // 第二个参数,构造合法的sql语句 // insert into person(name) values(null); } public void update(Person person) { database = dataBaseOpenHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("name", person.getName()); values.put("age", person.getAge()); database.update("person", values, "personid=?", new String[] { String .valueOf(person.getPersonid()) }); } public Person find(Integer id) { database = dataBaseOpenHelper.getReadableDatabase(); Cursor cursor = database.query("person", new String[] { "personid", "name", "age" }, "personid=?", new String[] { String .valueOf(id) }, null, null, null); if (cursor.moveToNext()) { return new Person(cursor.getInt(0), cursor.getString(1), cursor .getShort(2)); } return null; } public void delete(Integer... ids) { if (ids.length > 0) { String[] strIds = new String[ids.length]; StringBuilder sb = new StringBuilder(); for (int i = 0; i < ids.length; i++) { sb.append('?').append(','); strIds[i] = String.valueOf(ids[i]); } sb.deleteCharAt(sb.length() - 1); database = dataBaseOpenHelper.getWritableDatabase(); database.delete("person", "personid in(" + sb + ")", strIds); } } /** * * query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)方法各参数的含义 * table:表名。相当于select语句from关键字后面的部分。如果是多表联合查询,可以用逗号将两个表名分开 * columns:要查询出来的列名。相当于select语句select关键字后面的部分 * selection:查询条件子句,相当于select语句where关键字后面的部分,在条件子句允许使用占位符"?" * selectionArgs:对应于selection语句中占位符的值,值在数组中的位置与占位符在语句中的位置必须一致,否则就会有异常 * groupBy:相当于select语句group by关键字后面的部分 * having:相当于select语句having关键字后面的部分 * orderBy:相当于select语句order by关键字后面的部分,如:personid desc, age asc; * limit:指定偏移量和获取的记录数,相当于select语句limit关键字后面的部分。 * */ public List<Person> getScrollData(int startResult, int maxResult) { List<Person> persons = new ArrayList<Person>(); database = dataBaseOpenHelper.getWritableDatabase(); Cursor cursor = database.query("person", new String[] { "personid", "name", "age" }, null, null, null, null, "personid desc", startResult + "," + maxResult); while (cursor.moveToNext()) { persons.add(new Person(cursor.getInt(0), cursor.getString(1), cursor.getShort(2))); } return persons; } public long getCount() { database = dataBaseOpenHelper.getReadableDatabase(); Cursor cursor = database.query("person", new String[] { "count(*)" }, null, null, null, null, null); while (cursor.moveToNext()) { return cursor.getLong(0); } return 0; } }
PersonServiceTest
package org.wp.db; import java.util.List; import org.wp.domain.Person; import org.wp.service.OtherPersonService; import org.wp.service.PersonService; import android.test.AndroidTestCase; import android.util.Log; public class PersonServiceTest extends AndroidTestCase { private static final String TAG = "PersonServiceTest"; public void testSave() throws Exception { // PersonService personService = new PersonService(this.getContext()); OtherPersonService personService = new OtherPersonService(this .getContext()); personService.save(new Person("某某某", (short) 23)); } public void testFind() throws Exception { // PersonService personService = new PersonService(this.getContext()); OtherPersonService personService = new OtherPersonService(this .getContext()); Person person = personService.find(1); Log.i(TAG, person.toString()); } public void testUpdate() throws Exception { // PersonService personService = new PersonService(this.getContext()); OtherPersonService personService = new OtherPersonService(this .getContext()); Person person = personService.find(1); person.setName("张三"); person.setAge((short) 11); personService.update(person); person = personService.find(1); Log.i(TAG, person.toString()); } public void testGetCount() throws Exception { // PersonService personService = new PersonService(this.getContext()); OtherPersonService personService = new OtherPersonService(this .getContext()); Log.i(TAG, String.valueOf(personService.getCount())); } public void testGetScrollData() throws Exception { // PersonService personService = new PersonService(this.getContext()); OtherPersonService personService = new OtherPersonService(this .getContext()); // for (int i = 0; i < 10; i++) { // personService.save(new Person("某某某" + i, (short) (i + 1))); // } List<Person> persons = personService.getScrollData(0, 30); for (Person person : persons) { Log.i(TAG, person.toString()); } } public void testDelete() throws Exception { PersonService personService = new PersonService(this.getContext()); personService.delete(1, 2, 3); } }
Person
package org.wp.domain; public class Person { private Integer personid; private String name; private Short age; public Person(Integer personid, String name, Short age) { this.personid = personid; this.name = name; this.age = age; } public Person(String name, Short age) { this.name = name; this.age = age; } public Integer getPersonid() { return personid; } public void setPersonid(Integer personid) { this.personid = personid; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Short getAge() { return age; } public void setAge(Short age) { this.age = age; } @Override public String toString() { return "personid=" + personid + ",name=" + name + ",age=" + age; } }
main.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" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button" android:id="@+id/button" /> </LinearLayout>
strings.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, DBActivity!</string> <string name="app_name">数据库应用</string> <string name="button">操作数据库</string> </resources>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.wp.db" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <uses-library android:name="android.test.runner" /> <activity android:name=".DBActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="7" /> <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="org.wp.db" android:label="Tests for My App" /> </manifest>
相关推荐
"Android学习笔记" Android学习笔记是Android开发者的必读书籍,书中涵盖了Android系统架构、Activity、Intent、资源管理等多方面的知识。本笔记对应的学习资源《第一行代码》是Android开发者的入门必读书籍,书中...
Android学习笔记(一)——创建第一个Android项目 Android学习笔记(二)android studio基本控件及布局(实现图片查看器) Android学习笔记(三)android studio中CheckBox自定义样式(更换复选框左侧的勾选图像) ...
### Android学习笔记 #### 1. Android概述 **1.1 Android的特性** - **应用框架**:Android提供了一个强大的应用框架,使得开发者能够轻松地重用基础组件和服务,简化了应用程序的开发流程。 - **Dalvik虚拟机**...
### Android开发学习笔记 #### Button按钮的实现与交互 在Android开发中,`Button`控件是最常用的用户界面元素之一,用于触发特定的操作或事件。本文档将详细讲解如何创建并自定义一个简单的按钮,并设置点击事件...
【Android学习笔记】 Android平台是谷歌推出的一个开放源代码的移动设备操作系统,它为开发者提供了一个全面的软件包,包括操作系统、中间件和关键应用程序。这个平台的主要目标是促进移动应用的创新和多样性,允许...
Android学习笔记(1)-永远不变的Hello World Google的Android SDK发布也有一段时间了,一直想研究一下却苦于找不到时间。利用这个周未,开始强迫自己再次进入学习状态,原因很简单:我看好开放的gPhone。 SDK的下载...
Android开发学习笔记(整理),整理论坛android学习笔记,较完整的讲解了android的内容。包括:view、activity、service、intent、广播机制、http连接、数据sqllite存储、后台线程、各种layout、偏好、本地文件操作、...
这篇学习笔记主要涵盖了关于布局的一些基本概念,特别是`fill_parent`和`wrap_content`这两种尺寸指定方式,以及如何通过XML布局文件来精确控制组件的位置。 首先,`fill_parent`和`wrap_content`是Android布局中的...
根据给定的信息,我们可以从Java和Android学习笔记中提取出一系列重要的知识点,下面将逐一进行详细解释。 ### Java基础知识 #### 1. 命令行基础操作 - **`javacmd`**: 这个命令是Java命令行工具的一部分,用于...
Android学习笔记整理.pdf
Android学习笔记全全整理,是针对想要深入理解并掌握Android开发技术的学习者们的一份宝贵资源。这份笔记涵盖了从基础到高级的多个方面,旨在帮助读者建立起完整的Android知识体系。以下将详细介绍其中可能包含的...
本篇学习笔记主要涵盖了ArcGIS for Android的基础配置和核心组件MapVie的使用。 首先,配置ArcGIS for Android项目需要在`Project`级别的`build.gradle`文件中添加Esri的仓库,确保能获取到所需的库。接着,在`...
Android基础学习笔记主要涵盖了一系列关于Android开发的基本概念和关键组件,以下是这些知识点的详细解析: 1. **Activity**: 是Android应用程序的基本单元,它代表用户在屏幕上看到的一个界面。每个Activity都必须...
目录,整理论坛android学习笔记,较完整的讲解了android的内容。包括:view、activity、service、intent、广播机制、http连接、数据sqllite存储、后台线程、各种layout、偏好、本地文件操作、apdapter等几乎全部内容...
《Android学习笔记》 在移动应用开发领域,Android操作系统占据着重要的地位,为开发者提供了丰富的API和工具,使得创建各种应用程序变得可能。本压缩包文件包含了一位学习者从第一天到第五天,以及一个特定项目...
《黑马程序员Android学习笔记》是一份专为初学者设计的详尽教程,旨在帮助那些希望踏入安卓开发领域的人员快速掌握核心知识。这份笔记涵盖了从基础到进阶的多个主题,帮助学习者系统地理解Android应用开发的过程。 ...