Android个人每天总结.doc(day02 文件&数据库)
来源:互联网 发布:淘宝宝贝设置价格区间 编辑:程序博客网 时间:2024/06/03 16:44
作者:韩亚飞_yue31313_韩梦飞沙 QQ:313134555
day02 文件&数据库
Ø Android的试调与测试
一、debug试调
基本与web试调一致,定义断点,然后运行,只不过以前在网页配合,现在要在手机上配合
二、Junit测试Android
(一)手动配置
1. 在应用下定义一个继承AndroidTestCase类的测试类,且里面的所有测试方法以test小写开头
public class Testextends AndroidTestCase{
public voidtestCha(){
ContactService service=newContactService(getContext());
List<ContactPhone>list=service.getContact();
System.out.println(list);
}
2. 在AndroidManifest.xml加上以下配置
<?xml version="1.0"encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="read.phone"
android:versionCode="1"
android:versionName="1.0">
<uses-sdkandroid:minSdkVersion="10"/>
<uses-permissionandroid:name="android.permission.READ_CONTACTS"/>
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="read.phone" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<uses-libraryandroid:name="android.test.runner"/>
<activity ......
</application>
(二)自动配置
在建应用时选择需要测试方法,那么就会自动生成一个关联的测试应用.
(三)Android-Junit的测试原理
就是会生成一个测试的apk,发送到手机上去,然后创建要执行对象,运行要执行的方法,不般,不要activity界面
三、logcat日志的管理
system.err.println();异常打印用的是这个方法
提示信息级别
catch异常:就是黄警告没catch就是红
log类V() d() i() w() e()可以指定输出日志
logcat界面的管理
Ø 文件操作
一、写入文件到SD卡
需要在清单文件中注册权限
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2.1版本以下的SDCard位置和2.2之后版本不同
可以通过Environment.getExternalStorageDirectory()获取当前SDCard位置,兼容所有版本
获取SDCard状态--判断SD卡是否存在
通过Environment.getExternalStorageState()方法获取SDCard当前状态
常量 Environment.MEDIA_MOUNTED 为已安装
代码如下:
//获取sd卡路径
public void save2sd(String name, Stringcontent) throws IOException {
Filefile=Environment.getExternalStorageDirectory();
//组合文件路径
File fileName=new File(file, name);
//定义流
FileOutputStream fos=newFileOutputStream(fileName);
//写入到sd卡
fos.write(content.getBytes());
fos.close();
二、写入文件到rom
获取输出流,----写入--权限管理
通过Context.openFileOutput(String name, int mode)可以获取一个文件输出流
name为文件名,mode为文件模式,有4种模式
输出流指向路径为:/data/data/包名/files/
文件模式在Context中有定义常量,可以相加
0 私有 1可读 2 可写 3可读可写
MODE_PRIVATE 私有
MODE_WORLD_READABLE 其他程序可读(不可写)
MODE_WORLD_WRITEABLE 其他程序可写(不可读)
模式可以组合使用,例如:MODE_WORLD_READABLE+ MODE_WORLD_WRITEABLE
MODE_APPEND 追加
代码如下:
FileOutputStream fos=context.openFileOutput(name,Context.MODE_WORLD_READABLE+Context.MODE_WORLD_WRITEABLE);
fos.write(content.getBytes());
fos.close();
三、读取ROM中的文件
获取输入流---获取路径---输出
通过Context.openFileInput(Stringname)可以获取一个文件输入流
该输入流可以读取/data/data/包名/files/ 路径下的文件
获取当前程序Files文件路径
ContextWrapper.getFilesDir()
四、用XmlPullParser解析读取xml
获取XmlPullParser对象---关联资源文件得到输入流---解析器关联输入流并定义编码--获得Eventype事件方式--通过pullnext得到事件代码与事件方式代码来标识解析
(一)Xml.newPullParser() 获得解析器
(二)xmlPull.getEventType()获取事件方式
(三)parser.setInput(in, "UTF-8") 设置输入流以及编码
(四)parser.next() 获取下一个解析事件,得到一个事件代码
(五)XmlPullParser中定义了常量来标识各种解析事件--与事件方式比对
START_DOCUMENT、END_DOCUMENT、START_TAG 、END_TAG、TEXT
(六)代码事例如下:将xml读入集合
publicList<Person> pullXml() throws IOException, Exception {
// 建立集合
List<Person> list = newArrayList<Person>();
// 获取资源文件
InputStream in =PullXml.class.getClassLoader().getResourceAsStream(
"persons.xml");
// 建立资源文件输入流
// 获取pull对象
XmlPullParser xmlPull =Xml.newPullParser();
// 关联输入流
xmlPull.setInput(in,"utf-8");
Person p = null;
// 获取事件方式,是一个int 这个游标不从上往下不断行next,pull在解析到一个类型的标签时,
// 得到的事件方式值是不一样的,这样就可以根据不同的事件方式值,去判断进行什么样的处理.
// 通过type.next得到int值只要不是一个end_Document,则一直next下去
for (int type =xmlPull.getEventType(); type != XmlPullParser.END_DOCUMENT; type = xmlPull
.next()) {
// 只要读到开始标签,不管大还是小.就判断开始获取里面需要属性和内容.
if (type == XmlPullParser.START_TAG){
// 如果标签名是person,则建立一个Person对象,并且设制一个id
if("person".equals(xmlPull.getName())) {
p = newPerson();
p.setId(xmlPull.getAttributeValue(0));//表示取这个标签的第几个属性
// 如果是name就给标签设制一个name属性
} else if("name".equals(xmlPull.getName())) {
p.setName(xmlPull.nextText());
// 如果是age就给标签设制一个age属性
} else if("age".equals(xmlPull.getName())) {
p.setAge(Integer.parseInt(xmlPull.nextText()));
}
}
// 如果读到结束标签,且是person那么加入到集合中
if (type == XmlPullParser.END_TAG){
if("person".equals(xmlPull.getName())) {
list.add(p);
p = null;
}
}
}
return list;
}
五、XmlSerializer写文件到xml
得到应用file文件路径---再定义输出流关联文件---得到序列化xml工具--关联输出流与写义解码-
---写入---用序列化工具类以下方法写放:
startDocument
startTag
attribute
text
endTag
endDocument
String path = "/data/data/xml.demo/wr.xml";
OutputStream out=new FileOutputStream(path);
//获取xml序列化工具
XmlSerializerxmlSer=Xml.newSerializer();
xmlSer.setOutput(out, "UTF-8");
//用工具写入:两个参数后面的true表示不引用外部xml
xmlSer.startDocument("UTF-8", true);
//写放标标签,有属性就写属性,有文本就写文本
xmlSer.startTag(null, "persons");
for (Person p:pullXml()) {
xmlSer.startTag(null, "person");
xmlSer.attribute(null, "id", p.getId());
xmlSer.startTag(null, "name");
xmlSer.text(p.getName());
xmlSer.endTag(null, "name");
xmlSer.startTag(null, "age");
xmlSer.text(p.getAge()+"");
xmlSer.endTag(null, "age");
xmlSer.endTag(null, "person");
}
xmlSer.endTag(null, "persons");
xmlSer.endDocument();
}
}
偏好设制:SharedPreferences--类似于数据回显
获取对象---用setString("属性名",属性值)保存数据---获得Editor对象--用edit.putString("key值",没保存数据时的默认值).
不一定是String 可以是基本类型,如getInt setInt之类
(一)获取对象
Context.getSharedPreferences(Stringname,int mode)
在/data/data/<package>/shared_pref/目录下创建一个以name命名的xml文件,mode文件为模式
(二)保存数据--获得editor对象写入保存数据
调用edit()方法可以获取一个Editor对象,对数据进行存储,存储之后需要调用commit()保存到文件
(三)读取偏好数据,放入需要的标签
获得SharedPreferences之后调用getString()、getInt()等方法获取其中设置的值
获取SharedPreferences对象的另一种方式,
(四)在Activity中获取SharedPreferences不指定文件名
在Activity中可以调用getPreferences(int mode)方法获得一个SharedPreferences,文件名和Activity名一致
(五)代码事例:
public class SharedActivityextends Activity {
private EditText eT2;
private EditText eT1;
privateSharedPreferences sp;
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
eT1 = (EditText)findViewById(R.id.editText1);
eT2 = (EditText)findViewById(R.id.editText2);
sp = getSharedPreferences("config",MODE_PRIVATE);
//读出数据到EditText中
eT1.setText(sp.getString("phone","10086"));
eT2.setText(sp.getString("content","haha"));
}
public void save(View view) {
String phone = eT1.getText().toString();
String content = eT2.getText().toString();
//把数据保存入SharedPreferences
//用对象得到编辑器
Editor editor = sp.edit();
editor.putString("phone", phone);
editor.putString("content", content);
editor.commit();
Toast.makeText(getApplicationContext(),"保存成功", 0).show();
Ø 数据库(SQLite)
(一)是什么?
Android平台中嵌入了一个关系型数据库SQLite
(二)有什么用?
(三)怎么用?
1. 创建数据库及表及更新表
Android操作系统使用SQLite数据库,使用有两种方法获得数据库对象:
1.获取已经存在的数据库
SQLiteDatabasedb=SQLiteDatabase.openDatabase("/sdcard/zhycheng.db3",null,SQLiteDatabase.OPEN_READONLY);
最后是一个flag标记.表示,打开后是只读,还是能读写等.
第一个String参数是数据库在文件系统中的位置,第二个参数一般为null,第三个参数控制数据库打开的方式。
这样就获得了数据库对象。
2.自己创建数据库
新建一个类,继承SQLiteOpenHelper,添加未实现的方法
代码如下:
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class MyHelper extends SQLiteOpenHelper{
public MyHelper(Contextcontext, String name)
{
this(context,name,1);
}
public MyHelper(Contextcontext, String name,int version)
{
this(context,name,null,version);
}
public MyHelper(Contextcontext, String name,//数据库的名字
CursorFactoryfactory,
int version){
super(context, name,factory, version);
}
@Override
public voidonCreate(SQLiteDatabase db) {
db.execSQL("create table user(id int,name text)");
}
@Override
public voidonUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
获得的数据库位于/data/data/yourpackage/databases/zhycheng.db3
然后通过生成一个MyHelper类的对象,调用
MyHelper mh=new MyHelper(this,"zhycheng");
SQLiteDatabasedb=mh.getReadableDatabase();
SQLiteDatabasedb=mh.getWritableDatabase();
分别获得只读和可写的数据库。
获得数据库之后就可以进行数据库操作有以下两种方式操作数据库
使用代码创建数据库--定义一个类--因为数据库在用户设备.
定义类继承SQLiteOpenHelper
声明构造函数,4个参数
这个类继承一个SQLiteOpenHelper抽象类,这个类没有无参构造,只有四个有参的构造方法
所以调用父类有参构造
四个参数是:(Context context, String name,SQLiteDatabase.CursorFactory factory, int version)
context:环境对象,通过这个确认哪个应用的数据库 --通过外部传入
name:数据库文件的名字.可以直接写
factory:游标工厂.Sursor(结果集) 可以用null表示用默认工厂
version:数据库版本号:从1开始
重写一个建立数据库方法onCreate和一个更新数据库方法onUpgrade()
创建数据库类对象
getWritableDatabase()
重写onCreate()方法
重写upGrade()方法
public class DBFactoryextendsSQLiteOpenHelper {
publicDBFactory(Context context) {
① 通过构造方法创建数据库
super(context, "telephone.db", null, 1);
telephone.db表示数据库名称
}
② 创建表的代码定义在onCreate()方法中,数据库创建时就会生成表
public void onCreate(SQLiteDatabasedb) {
db.execSQL("create table person(_id Integer primary keyautoincrement,name varchar(100),phone Long)");
}
③ 把更新数据库代码放在onUpgrage()方法中
通过更改版本来执行更新,版本号只能增加,不能减少,手动来写.
public void onUpgrade(SQLiteDatabasedb,int oldVersion, int newVersion) {
在构造方法中,把版本号改大一点,这个方法就会执行
//比如在这里给数据库中增加一张表什么的.....
}
}
2. CRUD操作
注:sql语句通用格式:
sql语句格式:
insertinto 表名(属性名1,属性名2,....) values(?,?,?...) ---插入到哪里
deletefrom 表名 where 属性---从哪里删除属性是什么的一行数据
update表名 set 属性1,属性2..where 属性---通过什么改哪个表的什么属性
slecte属性名1,属性名2... from 表名 where 属性--根据什么属性从哪里查数据
注:insert into user values(7,datetime(CURRENT_TIMESTAMP,'localtime')) 这个sql语句表示:
插入即可时间:datetime(CURRENT_TIMESTAMP,'localtime')这个就是即刻时间.
和JDBC访问数据库不同,操作SQLite数据库无需加载驱动,不用获取连接,直接可以使用,
获取SQLiteDatabase对象之后通过该对象直接可以执行SQL语句
SQLiteDatabase.execSQL()
SQLiteDatabase.rawQuery()
getReadableDatabase()和getWritableDatabase()的区别
查看源代码后我们发现getReadableDatabase()在通常情况下返回的就是getWritableDatabase()拿到的数据库
只有在抛出异常的时候才会以只读方式打开
数据库对象缓存
getWritableDatabase()方法最后会使用一个成员变量记住这个数据库对象,下次打开时判断是否重用
SQLiteDatabase封装了insert()、delete()、update()、query()四个方法也可以对数据库进行操作
这些方法封装了部分SQL语句,通过参数进行拼接
两种CURD方法区别代码事例:
public class DBDao {
DBFactory helper;
publicDBDao(Context context) {
super();
this.helper =new DBFactory(context);
}
//db.execSQL("INSERT INTO person(name, balance)VALUES(?,?)", new Object[] { p.getName(), p.getBalance() });
public void insert(Person p){
SQLiteDatabase db=helper.getWritableDatabase();
ContentValues cv=new ContentValues();
cv.put("name",p.getName());
cv.put("phone",p.getPhone());
第二个参数是一个自动生成的行号,也就是说,cv等于空时,依然会插入一个只有id和行.
db.insert("person", "_id", cv);
db.close();
}
public void delete(Integer id){
SQLiteDatabase db=helper.getWritableDatabase();
//db.execSQL("delete from person where _id=?", newObject[]{id});
db.delete("person", "_id=?",new String[]{id+""});
db.close();
}
public void update(Person p){
SQLiteDatabase db=helper.getReadableDatabase();
//db.execSQL("update person set name=?,phone=? where_id=?", new Object[]{p.getName(),p.getPhone(),p.getId()});
ContentValues cv=new ContentValues();
cv.put("name",p.getName());
cv.put("name",p.getName());
db.update("person", cv, "_id=?", new String[]{p.getId()+""});
db.close();
}
public Personquery(Integer id){
SQLiteDatabase db=helper.getReadableDatabase();
//Cursor c=db.rawQuery("select name,phone from person where_id=?", new String[]{id+""});
Cursor c=db.query("person", new String[]{"name","phone"},"_id=?", new String[]{id+""},null, null,null);
Person p=null;
if (c.moveToNext()) {
p= new Person(id,c.getString(c.getColumnIndex("name")),c.getLong(c.getColumnIndex("phone")));
}
db.close();
return p;
}
publicList<Person> queryAll(){
List<Person>list=newArrayList<Person>();
SQLiteDatabase db=helper.getReadableDatabase();
//Cursor c=db.rawQuery("select _id,name,phone fromperson", null);
Cursor c=db.query("person", new String[]{"_id","name","phone"},null,null,null,null,null);
while(c.moveToNext()){
Person p=newPerson(c.getInt(c.getColumnIndex("_id")),c.getString(c.getColumnIndex("name")),c.getLong(c.getColumnIndex("phone")));
list.add(p);
}
db.close();
return list;
}
public CursorqueryAllCursor(){
SQLiteDatabase db=helper.getReadableDatabase();
Cursor c=db.rawQuery("select _id,name,phone from person",null);
//db.close();这里不能关,因为cursor在传递,还要用
return c;
}
publicList<Person> queryPage(int page,int pageSize){
int offset=(page-1)*pageSize;
List<Person>list=newArrayList<Person>();
SQLiteDatabase db=helper.getReadableDatabase();
Cursor c=db.query("person"
,new String[]{"_id","name","phone"}
,null,null,null,null,null
,offset+","+pageSize);
while(c.moveToNext()){
Person p=new Person(c.getInt(c.getColumnIndex("_id"))
,c.getString(c.getColumnIndex("name"))
,c.getLong(c.getColumnIndex("phone")));
list.add(p);
}
db.close();
return list;
}
}
3. 事务管理--数据库的方法
在sql操作之前开启事物--完成后设制事物成功--[-再sql操作,--再设置事物成功--]--最后结束事务
在使用SQLite数据库时可以用SQLiteDatabase类中定义的相关方法控制事务
① 开启事务:beginTransaction()
② 设置事务成功标记:setTransactionSuccessful()
③ 结束事务:endTransaction()
endTransaction()需要放在finally中执行,否则事务只有到超时的时候才自动结束,会降低数据库并发效率
注:是把最后一次成功点之前的事物提交.也就是前面可以有多个事务,只会把成功的事务提交.
在安卓中不是每个应用都需要有数据库,看需求.
(四)什么时候用?
SQLite是Android内置的,而一个应用具体要不要添加数据库,就看具体数据需求,看数据量大不大.
(五)有什么特点?
1. SQLite的自动主键列都用_id这个属性名.约定的,外健约束是不能改的
不然的话,查询的时候要重命名.
2. SQLite数据库中列一旦创建不能修改
如果一定要修改,需要重新创建表,拷贝数据
比较小巧,方便 存储数据不区分类型.可以乱来.声名一个数据类型,可以存其它类型
一个库,就是一个文件,文件里有多张表
web的数据库在服务器上,用户通过访问服务器得到数据
sql语句与mysql基本一样.
通过java代码来实现创建数据库和表,这点与其它数据库不一样.,因为数据库在用户设备.
3. 其他数据库不同的是SQLite存储数据时不区分类型
但_id属性除外
例如一个字段声明为Integer类型,我们也可以将一个字符串存入,一个字段声明为布尔型,我们也可以存入浮点数。
除非是主键被定义为Integer,这时只能存储64位整数
4. 创建数据库的表时可以不指定数据类型
,例如:
CREATE TABLE person(id INTEGER PRIMARY KEYAUTOINCREMENT, name VARCHAR(20))
CREATE TABLE person(id INTEGER PRIMARY KEYAUTOINCREMENT, name)
SQLite语句特点
支持大部分标准SQL语句,增删改查语句都是通用的,分页查询语句和MySQL相同
SELECT * FROM person LIMIT 20 OFFSET 10
SELECT * FROM person LIMIT 10,20
5. 数据库的创建与更新特点
数据库不存在,就会执行创建数据库方法
数据库存在,且版本没有变化,则直接打开
版本变化,则执行onUpgrade方法更新数据库
- Android个人每天总结.doc(day02 文件&数据库)
- Android个人每天总结.doc(1)
- Android个人每天总结.doc(1.1)
- Android个人每天总结.doc(Android构架 )
- Android个人每天总结.doc(day05网络应用)
- Android个人每天总结.doc(day03 ListView)
- Android个人每天总结.doc(day08 多媒体)
- Android个人每天总结.doc(day04四大组件之:内容提供者ContentProvider)
- Android个人每天总结.doc(day07四大组件之:广播接收者&服务Service)
- Android个人每天总结.doc(day06 多线程&Handler类&四大组件之:Activity)
- Android 个人每天总结 基础总结
- 每天10个面试题(day02)
- Android 读取doc文件
- Android 读取doc文件
- Android 读取doc文件
- Android 读取doc文件
- Android 读取doc文件
- Android 读取doc文件
- 占位
- Android个人每天总结.doc(day04四大组件之:内容提供者ContentProvider)
- Android个人每天总结.doc(day05网络应用)
- Android个人每天总结.doc(day03 ListView)
- Android个人每天总结.doc(day07四大组件之:广播接收者&服务Service)
- Android个人每天总结.doc(day02 文件&数据库)
- Android个人每天总结.doc(day08 多媒体)
- Android个人每天总结.doc(day06 多线程&Handler类&四大组件之:Activity)
- Ubuntu 下搜索程序、文件和文件内容
- python中dataframe合并
- 问题:jQuery Ready 与 Window onload 的区别
- hdoj5631Rikka with Graph
- Java Web学习(29): Servlet学习(二)
- [Go语言]我的第六个Go语言程序