本帖最后由 王震阳老师 于 2015-3-23 22:10 编辑
Android基础-03SQLite&ListView&常用控件
pdf内容回复可见:
1. Android SQLite数据库(★★★)SQLite,是一款轻量型的数据库,是遵守ACID(原子性、一致性、隔离性、持久性)的关联式数据库管理系统,多用于嵌入式开发中。 SQLite数据库是无类型的,可以向一个integer的列中添加一个字符串,但它又支持常见的类型比如: NULL, VARCHAR, TEXT, INTEGER, BLOB, CLOB等. :唯一的例外:integer primary key此字段只能存储64位整数。 1.1 Android中如何管理数据库在Android系统中,提供了一个SQLiteOpenHelper抽象类,该类用于对数据库版本进行管理。 该类中常用的方法: onCreate 数据库创建时执行(第一次连接获取数据库对象时执行) onUpgrade 数据库更新时执行(版本号改变时执行) onOpen 数据库每次打开时执行(每次打开数据库时调用,在 onCreate,onUpgrade方法之后) :由于SQLiteOpenHelper是一个抽象类,所以我们在用的时候可以自定义一个SQLiteOpenHelper类的子类来对数据库进行操作。
下面通过一个案例演示SQLiteOpenHelper的用法。创建一个Android工程。为该工程添加Android Junit测试环境(注意:关于Android Junit的知识在本人的第二篇笔记中有详细的说明)。 创建一个PersonOpenHelper类,继承SQLiteOpenHelper抽象类,重写onCreate和onUpgrade方法。 代码清单如下: 创建一个PersonOpenHelperTest类,用于测试上面的代码: 执行完上面代码后,通过DDMS,查看/data/data/com.itheima.sqlite/databases目录,发现产生了两个文件,person.db和person.db-journal。其中第一个文件就是我们的数据库文件。第一次操作数据库时,person.db-journal文件会被自动创建,该文件是sqlite的一个临时的日志文件,主要用于sqlite数据库的事务回滚操作了。 但是Android系统中将该文件永久的保存在磁盘中,不会被自动清除的,如果没有操作异常或者不需要事务回滚时,此文件的大小为0。这种机制避免了每次生成和删除person.db-journal文件的开销。
1.2 使用SQLiteDatabase操作数据库SQLiteDatabase(★★★) Android提供了一个名为SQLiteDatabase的类,该类封装了一些操作数据库的API,使用该类可以完成对数据进行添加(Create)、查询(Retrieve)、更新(Update)和删除(Delete)操作(这些操作简称为CRUD)。 常用方法: execSQL():可以执行insert、delete、update和CREATE TABLE 之类有更改行为的SQL语句。 rawQuery():用于执行select语句。 游标结果集Cursor(★★★) Cursor是结果集游标,用于对结果集进行随机访问。 Cursor与JDBC中的ResultSet作用很相似。 Cursor中维护一个行索引一个列索引,游标中本身没有数据,它只是指向数据库的索引,模拟一个行、列的表结构。其起始位置是在-1的位置上的。 常用方法: moveToNext():将游标从当前行移动到下一行,如果已经移过了结果集的 最后一行,返回结果为false,否则为true。
moveToPrevious():用于将游标从当前行移动到上一行,如果已经移过了 结果集的第一行,返回值为false,否则为true。 moveToFirst():用于将游标移动到结果集的第一行,如果结果集为空, 返回值为false,否则为true。 moveToLast():用于将游标移动到结果集的最后一行,如果结果集为空, 返回值为false,否则为true。 1.3 执行SQL语句操作数据库执行SQL语句来操作数据库有两种方式,拼串和使用占位符”?。使用占位符”?”来执行SQL语句能够防止SQL注入攻击。 拼串方式使用的方法: execSQL(String sql):增、删、改。 Cursor rawQuery(String sql, String[] selectionArgs): 查询(拼 串方式,第二个参数传null即可)。 占位符”?”使用的方法: void execSQL(String sql, Object[] bindArgs)。 Cursor rawQuery(String sql, String[] selectionArgs)。 :第二个参数对应的是第一个参数中占位符”?”对应的数据数组 下面通过一个案例来演示通过执行SQL实现对数据的增删改查操作,这里使用本文档中1.1章节中的工程(★★★★)。 在本文档1.1章节中,我们继续使用PersonOpenHelperTest类,在该测试类中添加如下方法: :在上面例子各个方法中,为了方便Android Junit测试,因此我把数据“写死”在代码里了,真正开发中是不会这么设计的。 1.4 使用SQLiteDatabase自带的增删改查方法SQLiteDatabase专门提供了对应于添加(insert)、删除(delete)、更新(update)、查询(query)的操作方法。 这些方法实际上是给那些不太了解SQL语法的开发者使用的(对我来讲直接通过sql操作数据库反而要简单的多,这两种操作数据库的方式要求都会,开发过程中用什么方法就要看个人习惯和公司有无特殊规定了),对于熟悉SQL语法的程序员而言,直接使用execSQL()和rawQuery()方法执行SQL语句就能完成数据的添加、删除、更新、查询操作。 下面通过代码来演示SQLiteDatabase操作数据库的过程,我们这里直接使用本文档1.1中工程,只需修改PersonOpenHelperTest类中方法即可。 至此,本小节完! 1.5SQLite数据库的事务操作跟MySql、Oracle等常用数据库一样,SQLite数据库也对事物有较好的支持。 使用方法: beginTransaction(): 开启一个事务 setTransactionSuccessful():设置成功点 endTransaction(): 结束事务,包括提交和回滚 执行过程: 使用beginTransaction开启一个事务,程序执行到endTransaction方法时会检查事务的标志是否为成功,如果程序执行到endTransaction之前调用了setTransactionSuccessful方法设置事务的标志为成功,则提交事务;如果没有调用setTransactionSuccessful方法则回滚事务。 那么下面通过一个案例演示SQLite操作事务的过程。为了便于直奔主题,我们直接使用本文档1.4章节中的Android工程中的PersonOpenHelperTest类即可。 案例:银行转账,需求:客户lisi向zhangsan的账户上转了100块。 1.6事务对效率的提高在批量修改数据的时候,由于事务是在进行事务提交时将要执行的SQL操作一次性打开数据库连接执行,其执行速度比逐条执行SQL语句的速度快了很多倍。因此当我们开发中遇到对数据库的批量操作那么,使用事务是提高效率的重要原则。 下面通过一个案例,来演示批量操作的情况下,使用事务和不使用事务在效率上的差异。同样的该案例依然使用本文档1.1中的Android工程。 案例:插入一万条数据到数据库,比较使用事务和不使用事务各自所需的时间。 执行上面代码,查看控制台,发现不使用事务耗时19397毫秒,使用事务耗时3404毫秒,性能差别还是相当的明显。 1.7 查看SQLite数据库查看SQLite数据库有多种方法,上面章节的演示过程其实就是通过Android API的方式查看。那么下面要介绍的是非常常用的两种方式:1、通过SQLite Expert工具2、通过Android sqlite3工具。 通过SQLite Expert工具 SQLite Expert( http://www.sqliteexpert.com/)是一款强大的SQLite数据库管理工具。从官网上下载的版本只能免费试用30天,试用期过后如果继续使用需要支付一定的费用购买许可。该工具的安装过程很简单,在这里就不再演示。只给大家演示如果利用该工具打开我们在上一个章节中生成的测试数据。 在DDMS视图中打开/data/data/com.itheima.sqlite/databases/person文件,点击右上角的导出按钮,然后在弹出的文件对话框中选择需要保存的位置,然后点击确定即可将模拟器中的数据库文件导出到本地。 然后打开SQLite Expert软件,将person数据拖拽到如下图的左侧区域即可。
通过Android sqlite3工具 Android提供了一个sqlite3.exe程序,位于sdk的tools目录下,用于操作SQLite数据库,其常用命令为: 1、sqlite3 数据库名称:进入数据库操作模式 eg: sqlite3 contacts.db 2、tables:查看所有的表 eg: .tables 3、schema:查看查看库中所有表的DDL语句 eg: .schema 4、help : 查看帮助 eg: .help 5、headers on/off :显示表头,默认off eg: headers on 6、mode list|column|insert|line|tabs|tcl|csv:改变输出格式 eg: .mode column 7、nullValue: NULL空值数据显示问题 eg: .nullValue NULL 8、dump表名 : 生成形成表的SQL脚本 eq: .dump person 9、dump : 生成整个数据库的SQL脚本 eq: .dump 9、exit : 退出sqlite操作模式 eq: .exit 操作步骤: - 在命令行界面使用adb shell命令进入linux内核
- 使用cd命令进入数据库所在目录(数据库的路径为”/data/data/应用包名/databases/数据库”)
- 使用”sqlite3 数据库名”进入数据库操作模式
- 直接使用各种命令操作数据库
2. ListView控件(★★★★) ListView是我们Android中最重要的控件之一,是用于对数据进行列表展示的控件。 :ListView的特点。 屏幕上可以展示几个控件, ListView就初始化几个,节省内存,防止内存溢出。 通过使用convertView对创建的视图对象进行复用,ListView始终保持创建的对。象个数为: 屏幕显示的条目的个数 + 1。 ListView自带ScrollView的功能,可以实现界面滚动。 ListView控件的设计遵循MVC设计模式: mode 数据模型(数据) :要被显示到ListView上的数据集合 view 视图(展示数据) : ListView controller控制层(把数据展示到空间上) : 适配器Adapter 下面我们依然通过案例来演示ListView的用法。 2.1读取数据库的数据并显示到ListView上在这里依然使用本文档1.1章节中的工程。在此工程上添加布局文件(2个,一个是Activity对应的布局文件,另外一个是用于显示用户的一条记录,指定ListView数据项的展示样式)。 ListView展示样式效果如下: 。 :布局文件的名字必须全部都是小写字母! 创建ListView展示样式布局文件,文件名为listview_item.xml 创建业务类操作数据库,在该工程中新创建PersonDao 修改main_activity.xml布局文件 使用并修改该工程默认的Activity类,MainActivity。该类的主要业务功能有: (1)调用Dao获取数据库的全部数据 (2)获取ListView控件的实例 (3)自定义适配器,继承BaseAdapter,重写getCount以及getView方法 Int getCount():用于获取要展示的数据的总条数,即ListView的总长度 View getView(int position,View convertView,ViewGroup parent) position:当前要显示的项在ListView的索引 convertView:缓存对象,ListView中创建对象的个数=屏幕显 示的条目数+1,当滑动屏幕时,被隐藏的项会作为缓存对象,作为getView的参数传递进来。只需修改此缓存对象的内容,直接使用即可,而不需要再重新new一个新的对象出来,节省了内存,防止内存溢出。
至此,代码和布局文件清单均已经完成,运行程序后效果图如下。
2.2常见的适配器AdapterListView中使用的适配器有: BaseAdapter、ArrayAdapter、SimpleAdapter。在2.1章节中我们演示了BaseAdapter的用法。下面我们将通过两个案例分别介绍ArrayAdapter和SimpleAdapter。 2.3ArrayAdapterArrayAdapter不仅可以用于显示简单的文本,也可以显示样式和内容丰富的对象。在这里只演示其最简单的使用方法。为了方便演示,新创建一个Android工程,工程名字就叫Adapter,使用该工程默认的布局文件和Activity类。 布局清单如下: MainActivity代码清单如下: 运行该工程,效果图如下: 2.4SimpleAdapterSimpleAdapter可以实现比ArrayAdapter复杂一点的布局。使用SimpleAdapter的数据用一般都是HashMap构成的List,List的每一节对应ListView的每一行。HashMap的每个键值数据映射到布局文件中对应id的组件上。因为系统没有对应的布局文件可用,我们可以自己定义一个布局文件。在本文档中我们用TextView和ImageView组合来进行布局以演示SimpleAdapter的用法。布局效果如下图: 该布局,采用LinearLayout水平布局。为了直奔主题,我们直接修改本文档2.4中的MainActivity类即可,使用默认的main_activity.xml布局文件,另外需要创建上图的布局文件,该布局文件清单如下: MainActivity类代码清单: 运行该工程效果如下图: 3. Android中的对话框(★★★)Android中常用的对话框有通知对话框、列表对话框、单选对话框、多选对话框以及进度对话框。其中,通知对话框、列表对话框、单选以及多选对话框由AlertDialog.Builder创建,进度对话框由ProgressDialog创建。 常用方法: setIcon 设置对话框标题栏左侧的那个图标 setTitle 设置对话框标题栏的提示信息 setMessage 设置对话框主体部分的提示信息 setPositiveButton 设置确定按钮 setNegativeButton 设置取消按钮 setCancelable 设置对话框在点击返回键时是否会关闭 show 显示对话框 下面将通过案例分别介绍这五种对话框的用法。 :为了方便演示,在这里需要创建一个新工程,工程名叫《对话框》。该工程的主界面有五个按钮,这五个按钮绑定了分别调用其对应对话框的函数,点击不同的按钮在其对应的函数里展示不同的对话框。因此下面的操作默认都是在该工程中实现的。 该工程的布局文件清单如下: 该工程运行效果图如下: 3.1 通知对话框通知对话框使用Builder创建,一般都会有个确认和取消按钮。当通知对话框提示的信息是要求用户必须观看且必须做出确定或者取消的选择的时候,需要设置setCancelable属性为false(默认true),以防止用户直接使用返回键关闭对话框。 notifyDialog()方法代码清单: 运行效果图:
3.2 列表对话框列表对话框使用Builder来创建,只需调用Builder对象的setItems方法设置要展示的列表项即可。 执行上面的代码,运行效果如下图:
3.3 单选对话框单选对话框使用Builder来创建,只需调用Builder对象的setSingleChoiceItems方法,设置要展示的列表项即可。 setSingleChoiceItems(CharSequence[] items,//要展示的单选选项列表 int checkedItem,//默认选中项的索引 final OnClickListener listener)//选中选项触发的点击事件
:该种类型的对话框在点击选项的时候Toast即输出您点击的条目,但是此时该对话框并没有自动消息,需要我们点击确定和取消才会消失。而列表对话框在我们选种任何一个条目后对话框自动就消失。 3.4 多选对话框多选对话框使用Builder来创建,只需调用Builder对象的setMultiChoiceItems方法,设置要展示的列表项即可。
setMultiChoiceItems(CharSequence[] items, //要展示的多选列表项 boolean[] checkedItems, //对应每个列表项的选中状态 final OnMultiChoiceClickListener listener)//点击事件 运行上面代码效果如下图: 3.5 进度对话框进度对话框不同于之前几种对话框,它是由ProgressDialog对象来创建的,而且进度对话框内部使用了消息机制Handler来进行处理,所以它可以直接在子线程中进行修改,无需再单独设置Handler来修改UI。 运行上面代码效果如下图:
至此,常见的对话框都已经演示完毕! 4. Android中几个常用控件(★★★)在本章节中我们将用介绍ProgressBar、Spinner、AutoCompleteTextView、MultiAutoCompleteTextView等共四个控件的基本用法。这些控件在我们以后的工作中经常会用到的,因此这里也要求我们必须掌握这部分知识。 :为了便于演示我们新创建一个项目,项目名《常用控件》。使用默认的布局文件和默认的Activity类。 布局文件如下: 布局文件完! :在上面布局文件清单中Spinner控件有个比较特殊的属性需要引入外部文件。android:entries="@array/cities"。该属性值是一个布局文件,需要在工程中res/values/strings.xml中添加。下面不是strings.xml的文件清单,其中黄色背景是新添加的字符串常量,作为Spinner的备选项。
MainActivity代码清单如下:
代码清单完毕! 4.1 进度条ProgressBar进度条,与进度对话框有着类似的功能,也可以直接在子线程中控制其进度的改变。不同的是进度条一般嵌入在我们自定义的布局文件中,而进度对话框则单独占据一个布局(该布局系统自带提供)。 4.2下拉列表框SpinnerSpinner 是一个列表选择框,会在用户选择后,展示一个列表供用户进行选择。Spinner是ViewGroup的间接子类,它和其他的Android控件一样,数据需要使用Adapter进行封装。 4.3自动提示文本框AutoCompleteTextViewAutoCompleteTextView和EditText组件类似,都可以输入文本。AutoCompleteTextView组件可以和一个字符串数组或List对象绑定,当用户输入一个及以上字符时,系统将在AutoCompleteTextView组件下方列出字符串数组中所有以输入字符开头的字符串(只能提示一次)。这一点和 www.baidu.com、 www.google.com的搜索框非常相似,当输入某一个要查找的字符串时,搜索框就会列出以这个字符串开头的最热门的搜索字符串列表。 4.4多个自动提示文本框MultiAutoCompleteTextView功能类似AutoCompleteTextView,只不过AutoCompleteTextView只能提示一次,再遇到短信多人发送的情况时,只提示一次的AutoCompleteTextView使用不是很合适,所以就有了MultiAutoCompleteTextView。 调用MultiAutoCompleteTextView.setTokenizer方法为此控件设置一个值与值之间的分隔符即可,其余设置于AutoCompleteTextView类似。
|