作者:韩亚飞_yue31313_韩梦飞沙 QQ:313134555
第一节、 Android文本数据操作
一、知识概括
1、数据持久化操作
2、xml文件的Pull解析
3、xml文件的Pull生成
4、数据库操作
二、知识总结
1、Android中的junit测试
黑盒测试:不知道软件的源代码,从软件的界面和功能上测试软件工作是否正常.
边界用户案例.
白盒测试
知道软件的源代码, 对软件的某个方法,某个功能,某个模块,进行测试.
测试粒度:
测试方法: junit的框架进行方法测试.
测试功能: function test. 一般会有测试用例(user story)
测试模块: 集成测试,与服务器联调.
Junit测试需要配置清单文件
manifest节点下配置
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="cn.itcast.junit"/>
application节点下配置
<uses-libraryandroid:name="android.test.runner" />
Junit测试要继承AndroidTestCase这个类
其中AndroidTestCase这个类下面的两个方法要掌握
setUp() 在第一次被创建的时候 ,做一些初始化全局变量的操作
tearDown()在被销毁的时候 ,做一些结尾的操作.
2、数据持久化1、saveToRom
核心代码
获取文件路径,通过content(上下文)中的openFileOutput获取文件的输出流路径创建出一个默认路径下的:data/data/<包名>/files/config.txt
openFileOutput方法中可以设置创建出来的文件的操作权限
openFileOutput()方法的第二参数用于指定操作模式,有四种模式,分别为: Context.MODE_PRIVATE = 0
Context.MODE_APPEND = 32768
Context.MODE_WORLD_READABLE= 1
Context.MODE_WORLD_WRITEABLE= 2
public voidsaveToRomFile(String name ,String pwd){
// 私有的权限创建一个 config.txt的文件 并且获取到他的输出流
try {
FileOutputStream fos = context.openFileOutput("config.txt", Context.MODE_WORLD_WRITEABLE|Context.MODE_WORLD_READABLE);
Stringcontent = name+":"+pwd;
fos.write(content.getBytes());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
获取文件路径输入流路径,通过上下文的openFileInput方法包装出一个文件写入路径。
FileInputStream fis =this.openFileInput("config.txt");
FileInputStream fis =this.openFileInput("config.txt");
ByteArrayOutputStream bos =new ByteArrayOutputStream();
byte[] buffer = newbyte[1024];
int len;
while((len =fis.read(buffer))!=-1){
bos.write(buffer, 0,len);
}
byte[] result =bos.toByteArray();
String content = newString(result);
// zhangsan: 123456
String[] array =content.split(":");
//把数据重新设置到文本框里面
mEtName.setText(array[0]);
mEtPwd.setText(array[1]);
文件权限管理
在文件管理啊窗口的permissions 节点显示了文件的权限,代表linux系统文件的访问权限。
第一个“-” -代表文件 d 代表目录,后面的每三位代表一组权限
- | rw- | rw- | ---
当前用户 用户组 其他人
3、数据持久化2、saveToSDcard
清单文件权限
<!-- 在SDCard中创建与删除文件权限-->
<uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
核心代码
要往SDCard存放文件,程序必须先判断手机是否装有SDCard,并且可以进行读写。
注意:访问SDCard必须在AndroidManifest.xml中加入访问SDCard的权限
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File sdCardDir =Environment.getExternalStorageDirectory();//获取SDCard目录
File saveFile = new File(sdCardDir, “itcast.txt”);
FileOutputStreamfos= new FileOutputStream(saveFile);
fos.write("要存入的内容".getBytes());
fos.flush();
fos.close();
}
Environment.getExternalStorageState()方法用于获取SDCard的状态,如果手机装有SDCard,并且可以进行读写,那么方法返回的状态等于Environment.MEDIA_MOUNTED。
Sd卡存储容量的获取方法
public voidtestSDsize() throws Exception{
File path = Environment.getExternalStorageDirectory();
StatFs stat = newStatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks =stat.getBlockCount();
long totalbytes = blockSize*totalBlocks;
System.out.println(totalbytes);
}
4、SharedPreferences 保存参数的接口
文件存放在/data/data/<package name>/shared_prefs目录下,通过map集合将数据保存起来。
public class DemoActivity extends Activityimplements OnClickListener {
private EditText mEtName;
private EditText mEtPwd;
private Button mBtLogin;
private CheckBox mCb;
private SharedPreferences sp; // 用来保存参数的接口
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mEtName = (EditText)this.findViewById(R.id.et_name);
mEtPwd= (EditText) this.findViewById(R.id.et_pwd);
mBtLogin = (Button)this.findViewById(R.id.bt_login);
mCb = (CheckBox)this.findViewById(R.id.cb_remember_pwd);
// 初始化 sharedpreference
SharedPreferences sp = this.getSharedPreferences("config.txt", Context.MODE_WORLD_READABLE|Context.MODE_WORLD_WRITEABLE);
boolean issetup =sp.getBoolean("issetup", false);
if(issetup){
Stringname = sp.getString("name", "");
Stringpwd = sp.getString("pwd", "");
mEtName.setText(name);
mEtPwd.setText(pwd);}
mBtLogin.setOnClickListener(this);}
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_login:
String name =mEtName.getText().toString().trim();
String pwd =mEtPwd.getText().toString().trim();
// 得到sharedpreference的编辑器
Editor editor = sp.edit();
editor.putString("name",name);
editor.putString("pwd",pwd);
editor.putBoolean("issetup",true);
// 清空编辑器里面的内容,个人觉得可以将这个功能单独定义在一个点击事件中
// editor.clear();
// 非常重要,在使用SharedPreferences的时候必须有提交的步骤,这样保证了数据的安全提交。
editor.commit();
Toast.makeText(this, "保存密码成功",Toast.LENGTH_SHORT).show();
break;
} } }
5、两个获取目录的方法:
getCacheDir()方法用于获取/data/data/<packagename>/cache目录
getFilesDir()方法用于获取/data/data/<packagename>/files目录
6、xml文件的Pull解析
Assetrt目录的使用
AssetManagermanager = context.getAssets();//获取Assetrt目录路径的方法
InputStream is = manager.open("文件名"); //通过open方法获取一个写入路径
Pull解析核心代码
Pull解析就是通过对xml文件的标签事件类型的判断,分析当前标签对应的数据类型,并拆取出来,将数据定义到一个javabean中,从而获取数据
publicList<Person> getPersons(String filename){
AssetManager manager =context.getAssets();
try {
InputStream is = manager.open(filename);
//在android下使用pull解析xml文件
//1.获取pull解析器的实例
XmlPullParser parser = Xml.newPullParser();
//2.设置解析器的一些参数
parser.setInput(is,"utf-8");
// 获取pull解析器对应的事件类型
int type =parser.getEventType();
Person person = null;
List<Person> persons= new ArrayList<Person>();
while(type!=XmlPullParser.END_DOCUMENT){
if(type==XmlPullParser.START_TAG){
if("person".equals(parser.getName())){
person= new Person();
int id=Integer.parseInt( parser.getAttributeValue(0));
person.setId(id);
}elseif("name".equals(parser.getName())){
Stringname = parser.nextText();
person.setName(name);
}elseif("age".equals(parser.getName())){
intage = Integer.parseInt( parser.nextText());
person.setAge(age);
}
}
if(type==XmlPullParser.END_TAG){
if("person".equals(parser.getName())){
persons.add(person);
person= null;
}}
type = parser.next();}
return persons;
}
7、xml文件的Pull生成
/**
* 把persons集合里面的内容写到xml文件里面
*@param persons person的集合
*@return
*/
public booleansavePersonToXml(List<Person> persons){
try {
XmlSerializer serializer = Xml.newSerializer();
// /sdcard/person.xml
// mount unmount 文件系统的权限
File file = newFile(Environment.getExternalStorageDirectory(),"person.xml");
FileOutputStream fos = newFileOutputStream(file);
serializer.setOutput(fos,"utf-8");
serializer.startDocument("utf-8",true);
serializer.startTag(null,"persons");
for(Person person:persons){
serializer.startTag(null,"person");
serializer.attribute(null,"id", person.getId()+"");
serializer.startTag(null,"name");
serializer.text(person.getName());
serializer.endTag(null,"name");
serializer.startTag(null,"age");
serializer.text(person.getAge()+"");
serializer.endTag(null,"age");
serializer.endTag(null,"person");
}
serializer.endTag(null,"persons");
serializer.endDocument();
fos.flush();
fos.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
} }
8、创建数据库
Android中的数据库要继承SQLiteOpenHeloper()类
在继承这个类的时候会继承两个方法
onCreat():在对应的目录第一次生成数据库的时候会调用到这个方法,可以生成数据库表结构及添加一些应用使用到的初始化数据
onUpGrade():数据库的版本发生变换的时候会调用这个方法,一般在软件升级时才需改变版本号
数据可的创建代码:
public classMyDBOpenHelper extends SQLiteOpenHelper {
/**
*@param context 应用程序上下文
*@param name 数据库的名字
*@param factory 查询数据库的游标工厂 一般情况下 用sdk默认的
*@param version 数据库的版本 版本号必须不小1
*/
public MyDBOpenHelper(Context context) {
super(context,"itheima.db", null, 5);}
// 在mydbOpenHelper 在数据库第一次被创建的时候 会执行onCreate();
public void onCreate(SQLiteDatabase db) {
System.out.println("我被调用了 oncreate");
db.execSQL("CREATE TABLEperson (personid integer primary key autoincrement, name varchar(20))");}
public void onUpgrade(SQLiteDatabase db,int oldVersion, int newVersion) {
System.out.println("on update");
db.execSQL("ALTER TABLEperson ADD phone VARCHAR(12) NULL ");
}}
getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。但getWritableDatabase() 方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用getWritableDatabase()打开数据库就会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。
通过数据库的操作语句来执行增删改查的操作,这些操作需要调用到数据库中的命令语句:
a数据库的操作方法代码:
public classPersonDao {
private static final String TAG ="PersonDao";
private MyDBOpenHelper dbOpenHelper;
// 在personDao被new出来的时候 就完成初始化
public PersonDao(Context context) {
dbOpenHelper = new MyDBOpenHelper(context);
//dbOpenHelper.getReadableDatabase()
//dbOpenHelper.getWritableDatabase()
}
// 增删改查
b往数据库添加一条数据
public void add(String name, Stringphone) {
boolean result = find(name);
if (result)
return;
SQLiteDatabasedb = dbOpenHelper.getWritableDatabase();
if (db.isOpen()) {
db.execSQL("insertinto person (name,phone) values (?,?)",
new Object[]{ name, phone });
// 关闭数据库 释放数据库的链接
db.close();
}
}
c查找数据库的操作
public boolean find(String name) {
boolean result = false;
SQLiteDatabasedb = dbOpenHelper.getReadableDatabase();
if (db.isOpen()) {
Cursor cursor =db.rawQuery("select * from person where name=?",
new String[]{ name });
if (cursor.moveToFirst()) {
int index =cursor.getColumnIndex("phone"); // 得到phone在表中是第几列
String phone =cursor.getString(index);
Log.i(TAG,"phone =" + phone);
result = true;}
// 记得关闭掉 cursor
cursor.close();
result = false;
// 释放数据库的链接
db.close();
}
return result;}
d删除一条记录
public void delete(String name) {
SQLiteDatabase db =dbOpenHelper.getWritableDatabase();
if (db.isOpen()) {
db.execSQL("deletefrom person where name =?",
new Object[]{ name });
db.close();
}}
e更新一条记录
public void update(String name, Stringnewname, String newphone) {
SQLiteDatabase db =dbOpenHelper.getWritableDatabase();
if (db.isOpen()) {
db.execSQL("updateperson set name=? , phone=? where name=?",
new Object[]{ newname, newphone, name });
db.close();
}}
f查找全部
public List<Person> getAllPersons(){
List<Person> persons=null;
SQLiteDatabase db =dbOpenHelper.getReadableDatabase();
if (db.isOpen()) {
persons = newArrayList<Person>();
Cursor cursor =db.rawQuery("select * from person ", null);
while (cursor.moveToNext()){
Person person = newPerson();
int nameindex =cursor.getColumnIndex("name");
int phoneindex =cursor.getColumnIndex("phone");
String name =cursor.getString(nameindex);
String phone =cursor.getString(phoneindex);
person.setName(name);
person.setNumber(phone);
persons.add(person);
}
cursor.close();
db.close();
}
return persons;
}}
安卓模拟器可以通过自身的方法查看数据库
在doc下: adb shell---进入数据库所在的文件夹---sqlite3 数据库名。