day02 数据存储方式

经验总结:1.开发中不经常使用XML经常使用JSON,开发中要写单独的UNIT单元测试类,单独的工具类封包,开发中bean不要使用私有,要共有,如果使用bean的话或使用反射框架,消耗手机内存 ,安卓开发文档中有明确说明

问题:sharedpreference存储在那个地方,默认的sharedpreference存储在哪,生命周期是什么

1.点击按钮的4中监听方法

1.匿名内部类

2.创建一个类实现OnclickListener,setOnClickListener时传类的一个对象

3.让当前类实现OnclickListener,setOnClickListener时传this,在公司开发中一般用这种方式,用swich判断是哪个按钮

4.在布局文件中为控件添加一个onclick属性,在对应的activity中写一个以onclick属性值为名的方法,记住要 public, 名字对应,参数必须是View类型,内部实现是反射技术。一般开发不用,简单测试时使用.

2.安卓中的常用5大布局

1.线性布局 LinearLayout 垂直和水平 ; 要么从左到右,要么从上到下

padding:当前控件的子控件距离当前控件的长度

margin: 当前控件相对于四周控件或父控件的距离

layout_gravity:当前控件相对于父控件的对其方式

gravity:当前控件中的子控件相对于当前控件的对其方式

2.相对布局 RelativeLayout 要指定每个控件之间的相对位置,否则都从左上角开始布局

layout_above:位于哪个控件的上方

layout_below:位于哪个控件的下方

layout_toRightOf:位于哪个控件的右方

layout_toLeftOf:位于哪个控件的左方

layout_alignParentLeft:位于父窗体的左侧

layout_alignParentRight:

layout_alignParentBottom

layout_alignParentTop:

layout_centerInParent:位于父窗体的中心

layout_alignLeft:与哪个控件的左侧对其

layout_alignRigth:

layout_alignTop

layout_alignBottom

3.帧布局 FrameLayout 一层一层向上叠加布局

4.表格布局 TableLayout

TableLayout中的一个TableRow代表一行,TableRow中的一个控件代表一列

5.绝对布局 (被google抛弃)

3.测试的相关概念

1.按照是否知道代码划分

白盒测试 :知道源码

黑盒测试 :不知道代码

2.按照测试的粒度

a.方法测试

b.单元测试 Junit

c.系统测试

d.集成测试

3.按照测试的暴力程度

a.冒烟测试

b.压力测试 12306

android中的压力测试 : adb shell指令: monkey -p packagename count;

coun表示点击多少下

百度云测:第三方测试平台

4将数据存储到文件中

逻辑步骤:

1.写布局

LinearLayout + RelativeLayout

两个EditText 一个 CheckBox 一个Button

2.写业务逻辑

a.找到所需的控件

b.为按钮设置点击事件监听器

c.在onclick方法中获取用户输入的用户名,密码,是否记住密码

d.判断用户名密码是否为kong,不为空,执行登陆,为null时提示用户

e.执行登陆 (默认登陆成功,省略)

f.判断是否记住密码,记住密码需要将密码保存到本地

g.如果保存的有密码,下次进入程序,需要将用户名密码回显。

***********使用Context对象获取私有目录:/data/data/packagename/files

String path = context.getFilesDir().getPath();

代码:

存储工具类

publicclassStoregeUtil {

Stringpath="/data/data/com.example.day02_login";

publicbooleansavedata(Context con,String name,String psw) {

//TODOAuto-generated method stub

String info=name+"##"+psw;

//              FileOutputStream out=new FileOutputStream(new File(path,"info.txt"));

//              out.write(info.getBytes());

try{

//使用该方法表示打开一个私有目录的输出流,不需要再确认路径,目录路径为/data/data/com.example.day02_login/file

FileOutputStream out=con.openFileOutput("info.txt", con.MODE_PRIVATE);

out.write(info.getBytes());

returntrue;

}catch(FileNotFoundException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}catch(IOException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}

returnfalse;

}

publicMap getinfo(Context con) {

//TODOAuto-generated method stub

try{

//              FileInputStream in=new FileInputStream(new File(path,"info.txt"));

//

FileInputStream in=con.openFileInput("info.txt");

BufferedReader bf=newBufferedReader(newInputStreamReader(in));

String info=bf.readLine();

Map mp=newHashMap();

mp.put("name", info.split("##")[0]);

mp.put("psw", info.split("##")[1]);

returnmp;

}catch(FileNotFoundException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}catch(IOException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}

returnnull;

}

}

主类

publicclassMainActivityextendsActivityimplementsOnClickListener {

EditTextinput_name;

EditTextinput_psw;

CheckBoxcheck_rem;

StoregeUtilutil=newStoregeUtil();

@Override

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.login_index);

// 获取需要的空间id

input_name= (EditText) findViewById(R.id.input_name);

input_psw= (EditText) findViewById(R.id.input_psw);

check_rem= (CheckBox) findViewById(R.id.check_remeberpsw);

Button bt_login = (Button) findViewById(R.id.bt_login);

bt_login.setOnClickListener(this);

Map map=util.getinfo(this);

if(map==null)

{

return;

}else

{

input_name.setText(map.get("name"));

input_psw.setText(map.get("psw"));

check_rem.setChecked(true);

}

}

@Override

publicvoidonClick(View v) {

intm = v.getId();

switch(m) {

caseR.id.bt_login:

String name =input_name.getText().toString().trim();

String string =input_psw.getText().toString();

//注意判断输入是否为空

if(TextUtils.isEmpty(name)||TextUtils.isEmpty(string))

{

Toast.makeText(this,"输入不能为空",0).show();

return;

}

if(check_rem.isChecked())

{

booleanflag=util.savedata(this,name,string);

if(flag)

{

Toast.makeText(this,"保存数据成功",0).show();

}else

{

Toast.makeText(this,"保存数据失败",0).show();

}

}

break;

default:

break;

}

}

}

5将数据存入SD卡

工具类

publicbooleansave(Context con, String name, String psw) {

//开启输出流

String info=name+"##"+psw;

try{

//   FileOutputStream out=con.openFileOutput("info", con.MODE_PRIVATE);

//获取SD卡的路径 ,路径为/mnt/sccard/

String path=Environment.getExternalStorageDirectory().getPath();

FileOutputStream out=newFileOutputStream(newFile (path,"info.txt"));

out.write(info.getBytes());

returntrue;

}catch(FileNotFoundException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}catch(IOException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}

returnfalse;

}

publicMap returninfo(Context con) {

//TODOAuto-generated method stub

try{

String path=Environment.getExternalStorageDirectory().getPath();

FileInputStream in=newFileInputStream(newFile (path,"info.txt"));

Map mp=newHashMap();

BufferedReader br=newBufferedReader(newInputStreamReader(in));

mp.put("name",br.readLine().split("##")[0]);

mp.put("psw",br.readLine().split("##")[1]);

returnmp;

}catch(FileNotFoundException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}catch(IOException e) {

//TODOAuto-generated catch block

e.printStackTrace();

}

returnnull;

}

}

主类

publicclassMainActivityextendsActivityimplementsOnClickListener{

SPutilsutil=newSPutils();

privateEditTextet_name;

privateEditTextet_psw;

privateCheckBoxcb_rem;

privateButtonbt_login;

protectedvoidonCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

et_name= (EditText)findViewById(R.id.et_name);

et_psw= (EditText)findViewById(R.id.et_psw);

cb_rem= (CheckBox)findViewById(R.id.cb_rem);

bt_login= (Button)findViewById(R.id.bt_login);

//注册监听

bt_login.setOnClickListener(this);

if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))

{

Toast.makeText(this,"SD卡未能挂载", 0).show();

return;

}

//获取回显的数据

Map mp=util.returninfo(this);

if(mp!=null)

{

et_name.setText(mp.get("name"));

et_psw.setText(mp.get("psw"));

cb_rem.setChecked(true);

return;

}

}

@Override

publicvoidonClick(View v) {

String name=et_name.getText().toString().trim();

String psw=et_psw.getText().toString();

if(TextUtils.isEmpty(name)||TextUtils.isEmpty(psw))

{

Toast.makeText(this,"不能为空", 0).show();

return;

}

//检查SD卡的状态,是否挂载,存储量是否够

if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))

{

Toast.makeText(this,"SD卡未能挂载", 0).show();

return;

}

longsize_free=Environment.getExternalStorageDirectory().getFreeSpace();

longsize_usable=Environment.getExternalStorageDirectory().getUsableSpace();

//String size_free1=Formatter.formatFileSize(this, size_free1);

//String size_usable1=Formatter.formatFileSize(this, size_usable1);

//判断存储空间是否足够

//if(size_usable<100*1024*1024)

//         {

//              Toast.makeText(this, "存储空间不够     为", 0).show();

//              return;

//         }

if(util.save(this,name,psw))

{

Toast.makeText(this,"成功保存", 0).show();

}else

{

Toast.makeText(this,"没有保存", 0).show();

}

}

6.sharepreference存储数据

SharedPreferences数据是以xml方式存储在data/data/私有目录下的一个shared_pres文件夹下。

SharedPreferences一般用来存放一些标记性的数据,设置性的数据。

工具类

publicclassSPutils {

publicMap returninfo(Context con) {

//TODOAuto-generated method stub

SharedPreferences sh=con.getSharedPreferences("info.txt", con.MODE_PRIVATE);

Map mp=newHashMap();

mp.put("name",sh.getString("name",null));

mp.put("psw",sh.getString("psw",null));

returnmp;

}

publicbooleansave(Context con, String name, String psw) {

//TODOAuto-generated method stub

//获得sharedpreferece

SharedPreferences sh=con.getSharedPreferences("info.txt", con.MODE_PRIVATE);

Editor edit = sh.edit();

edit.putString("name", name);

edit.putString("psw", psw);

//确认写入

if(edit.commit())

{

returntrue;

}else{

returnfalse;}

}

7.xml解析

XML的序列化:

// 备份短信使用XmlSerializer

public static boolean backupSmsForAndroid(Context context,

ArrayList lists) {

try {

// 1.通过Xml类创建一个XmlSerializer对象

XmlSerializer xs = Xml.newSerializer();

// 2.设置XmlSerializer对象将xml写入到哪个文件中。

xs.setOutput(context.openFileOutput("smsbackup2.xml",Context.MODE_PRIVATE), "utf-8");//os:写入到哪个文件流中,encoding:流的编码

// 3.使用XmlSerializer对象序列化一个xml声明头 encoding:xml的编码 standalone:是否独立

xs.startDocument("utf-8", true);

// 4.序列化一个根节点 namespace:命名空间 name:标签的名称

xs.startTag(null, "Smss");

// 5.循环遍历list集合,序列化一条条短信

for (SmsBean smsBean : lists) {

xs.startTag(null, "Sms");

//写一个标签的属性 namespace:命名空间 name:属性的名称 value :属性的值

xs.attribute(null, "id", smsBean.id);

xs.startTag(null, "num");

xs.text(smsBean.num);//写入一个标签的值

xs.endTag(null, "num");

xs.startTag(null, "msg");

xs.text(smsBean.msg);//写入一个标签的值

xs.endTag(null, "msg");

xs.startTag(null, "date");

xs.text(smsBean.date);//写入一个标签的值

xs.endTag(null, "date");

xs.endTag(null, "Sms");

}

// 6.序列化一个根节点的结束节点

xs.endTag(null, "Smss");

// 7.完成xml的写入

xs.endDocument();

return true;

} catch (Exception e) {

e.printStackTrace();

}

return false;

}

pull解析XML(反序列化)

//恢复短信

public static int restoreSms(Context context) {

ArrayList lists = null;

SmsBean smsBean = null;

try{

//1.创建一个XmlPullParser对象

XmlPullParser xpp = Xml.newPullParser();

//2.设置要解析的文件的流 in :读取流 encoding:流的编码

xpp.setInput(context.openFileInput("smsbackup2.xml"),"utf-8");

//3.获取xml第一行的事件类型

int type = xpp.getEventType();

//4.循环判断事件类型是否文档结束

while (type!= XmlPullParser.END_DOCUMENT) {

String currentTagName = xpp.getName(); //获取当前标签的名称

//5.不是文档结束,判断是开始标签还是结束标签,解析每一行的内容以bean的方式封装到list集合中,并且获取下一行事件 的类型。

switch (type) {

case XmlPullParser.START_TAG:

if("Smss".equals(currentTagName)){

//初始化一个list集合

lists = new ArrayList();

}else if("Sms".equals(currentTagName)){

//初始化一个SmsBean对象,并解析出id

smsBean = new SmsBean();

smsBean.id = xpp.getAttributeValue(null, "id");

}else if("num".equals(currentTagName)){

smsBean.num = xpp.nextText();//获取内容

}else if("msg".equals(currentTagName)){

smsBean.msg = xpp.nextText();//获取内容

}else if("date".equals(currentTagName)){

smsBean.date = xpp.nextText();//获取内容

}

break;

case XmlPullParser.END_TAG:

//当前标签是结束标签并且是sms那么就将bean对象添加到list集合中

if ("Sms".equals(currentTagName)) {

lists.add(smsBean);

}

break;

default:

break;

}

//获取下一行的事件类型

type = xpp.next();

}

//6.返回集合的size就是成功恢复的条数

return lists.size();

}catch (Exception e) {

e.printStackTrace();

}

return 0;

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容