Android数据存储-文件操作
一、预备知识
1.Android中的MVC设计模式
MVC (Model-View-Controller):M是指逻辑模型,V是指视图模型,C则是控制器。一个逻辑模型可以对于多种视图模型,比如一批统计数据你可以分别用柱状图、饼图来表示。一种视图模型也可以对于多种逻辑模型。使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式,而C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新,这与《设计模式》中的观察者模式是完全一样。
MVC好处:从用户的角度出发,用户可以根据自己的需求,选择自己合适的浏览数据的方式。比如说,对于一篇在线文档,用户可以选择以HTML网页的方式阅读,也可以选择以pdf的方式阅读。从开发者的角度,MVC把应用程序的逻辑层与界面是完全分开的,最大的好处是:界面设计人员可以直接参与到界面开发,程序员就可以把精力放在逻辑层上。而不是像以前那样,设计人员把所有的材料交给开发人员,由开发人员来实现界面。在Eclipes工具中开发 Android采用了更加简单的方法,设计人员在DroidDraw中设计界面,以XML方式保存,在Eclipes中直接打开就可以看到设计人员设计的界面。
Android中界面部分也采用了当前比较流行的MVC框架,在Android中:
1) 视图层(View):一般采用XML文件进行界面的描述,使用的时候可以非常方便的引入。当然,如何你对 Android了解的比较的多了话,就一定可以想到在Android中也可以使用JavaScript+HTML等的方式作为View层,当然这里需要进行Java和JavaScript之间的通信,幸运的是,Android提供了它们之间非常方便的通信实现。
2) 控制层(Controller):Android的控制层的重任通常落在了众多的Acitvity的肩上,这句话也就暗含了不要在Acitivity中写代码,要通过Activity交割Model业务逻辑层处理,这样做的另外一个原因是Android中的 Acitivity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。
3) 模型层(Model):对数据库的操作、对网络等的操作都应该在Model里面处理,当然对业务计算等操作也是必须放在的该层的。就是应用程序中二进制的数据。
在Android SDK中的数据绑定,也都是采用了与MVC框架类似的方法来显示数据。在控制层上将数据按照视图模型的要求(也就是Android SDK中的Adapter)封装就可以直接在视图模型上显示了,从而实现了数据绑定。比如显示Cursor中所有数据的ListActivity,其视图层就是一个ListView,将数据封装为ListAdapter,并传递给ListView,数据就在ListView中现实。
2.Android中的文件操作
Android中的文件操作,类似于Java,因为它是基于JAVA的,所以JAVA中的文件操作思路同时适用于Android,文件操作采用一种流的概念,类似于水流和水池
输出流是像水池中注水,输入流是像外界输水
界面中的数据 -----输出 ----->>>文件 (输出流)
文件中的数据 -----输入 ----->>>界面 (输入流)
下面是JAVA关于流的一些概念(来自http://blog.csdn.net/liuxiaogangqq/article/details/25892667):
2.1 数据流
一组有序,有起点和终点的字节的数据序列。包括输入流和输出流
2.2 输入流(Input Stream)
程序从输入流读取数据源。数据源包括外界(键盘、文件、网络…),即是将数据源读入到程序的通信通道
2.3 输出流 (OutPut Stream)
程序向输出流写入数据。将程序中的数据输出到外界(显示器、打印机、文件、网络…)的通信通道
二、Android程序案例-文件读写操作的实现
1.布局方面只有一个TextView,一个EditText,两个Button ---View层
2.书写Model层,即FileService --Model层
package cn.edu.bzu.service; import android.content.Context; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; /** * MVC设计模式 * M:model V:view C:control * 文件操作的服务类,兼备文件读写的功能 * Created by monster on 2015/5/29. */ public class FileService { private Context context;//上下文 private String fileName; //文件的名字 public FileService(Context context, String fileName) {//构造方法,用于传入上下文 this.context = context; this.fileName = fileName; } /** * 保存文件 * 思路:创建文件输出流-->>创建文件读写器-->>创建缓冲器-->>写入操作 */ public boolean saveFile(String content){ BufferedWriter bw=null; // 缓冲区声明 boolean isSaveSuccess=false; try { FileOutputStream fileOutputStream=context.openFileOutput(fileName,context.MODE_PRIVATE); //创建输出流 OutputStreamWriter outputStreamWriter=new OutputStreamWriter(fileOutputStream); //创建读写器 bw=new BufferedWriter(outputStreamWriter); //创建一个使用默认大小输出缓冲区的缓冲字符输出流 bw.write(content); isSaveSuccess=true; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if (bw != null) { try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } return isSaveSuccess; } /** * 读取文件 * 创建输入流-->创建读写器-->>创建缓冲区-->>读取数据 */ public String read(){ BufferedReader br=null; String line; StringBuffer sb=new StringBuffer(); //用于添加数据 try { FileInputStream fileInputStream=context.openFileInput(fileName); //创建文件流 InputStreamReader inputStreamReader=new InputStreamReader(fileInputStream);//创建读写器 br=new BufferedReader(inputStreamReader); while ((line=br.readLine())!=null){ sb.append(line); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if(br!=null){ try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } return sb.toString(); } }
此部分代码为Model层,所以为了更好的使用,我们进行书写一个测试类:
FileServiceTest.java:
package cn.edu.bzu.test; import android.test.AndroidTestCase; import cn.edu.bzu.service.FileService; /** * 文件操作测试类,通过Android JUnit Test进行测试 * @author monster * date:2015-05-30 */ public class FileServieTest extends AndroidTestCase { public void testSave(){ FileService fileService=new FileService(getContext(), "test.txt"); fileService.saveFile("hello world"); } }
然后进行配置清单文件:
然后进行Android JUnit Test测试:
测试结果:成功
测试成功后书写控制层(Control)代码 --Control层
MainActivity.java:
package cn.edu.bzu.fileoperate; import cn.edu.bzu.service.FileService; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; /** * 通过点击按钮实现存储数据和读取数据 * @author monster * 使用MVC设计模式 * date:2015-05-30 */ public class MainActivity extends Activity implements OnClickListener{ private EditText edt_content; private Button btn_save,btn_read; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { edt_content=(EditText) findViewById(R.id.content); btn_save=(Button) findViewById(R.id.btn_save); btn_read=(Button) findViewById(R.id.btn_read); btn_save.setOnClickListener(this); btn_read.setOnClickListener(this); } @Override public void onClick(View v) { switch(v.getId()){ case R.id.btn_save: String content=edt_content.getText().toString(); //得到值 if(content!=null){ FileService fs=new FileService(MainActivity.this, "Information.txt"); //通过构造方法传入上下文和文件名 boolean isSuccessed=fs.saveFile(content); if(isSuccessed){ Toast.makeText(MainActivity.this, "数据保存成功",Toast.LENGTH_SHORT).show(); } }else{ Toast.makeText(MainActivity.this, "请输入您要保存的内容",Toast.LENGTH_SHORT).show(); } break; case R.id.btn_read: FileService fs=new FileService(MainActivity.this, "Information.txt"); String info=fs.read(); //读取的数据 if(info!=null){ edt_content.setText(info); //给EditText设定值 Toast.makeText(MainActivity.this, "读取数据成功",Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(MainActivity.this, "读取数据发生错误",Toast.LENGTH_SHORT).show(); } break; } } }
----->>> ok,大功告成
三、总结
从这个案例中,我们需要掌握:
1.Android MVC设计模式
2.Android文件操作的基本思路
3.JAVA异常处理机制
4.JUnit 进行单元测试
四、源代码下载地址: