Android学习之文件存储

今天做了下文件存储的小案例,并借此巩固一下Android中的单元测试及MVC的设计模式.

.AndroidMVC模式如下

技术分享

步骤1: 布局编辑:

布局页面及代码如下:

技术分享

<Button
        android:id="@+id/btnSave"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/etContent"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="39dp"
        android:text="@string/btn_tip_save" />

    <EditText
        android:id="@+id/etContent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="74dp"
        android:drawableLeft="@drawable/icon"
        android:ems="15"
        android:hint="@string/et_tip_writeContent"
        android:minLines="3" >
        
        <!-- ems长度 -->
        <requestFocus />
    </EditText>

其中:android:ems="15" 代表设置TextView或EditText的宽度为15个字符的宽度

 

步骤2:业务层编辑:

代码如下:

package com.example.savafile.service;

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;

import android.content.Context;

/**用于对页面的操作,此处为数据的保存与读取*/
public class FileService {

    private Context context;
    private String fileName;

    /**初始化上下文和文件名(路径)*/
    public FileService(Context context, String fileName) {
        this.context = context;
        this.fileName = fileName;
    }

    public boolean save(String content) {

        boolean isSaveSuccessed = false;
        BufferedWriter bw=null;

        try {
            //为Context建立输出流(数据流向程序外)
            //参数1为存储的文件名,  参数2 为MODE模式
            FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);//构建字节输出流
            OutputStreamWriter writer = new OutputStreamWriter(fos);//将字节输出流包装为字符输出流
            bw = new BufferedWriter(writer);//将字符输出流包装为缓存流?
            bw.write(content);//write与OutputStream的区别
            isSaveSuccessed = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{

            try {
                //write和fos为什么不用关闭呢?
                if (bw != null) {
                    bw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        return isSaveSuccessed;
    }

    public String read(){

        String line;
        StringBuilder sb = new StringBuilder();//作用是什么
        BufferedReader br = null;
        
        try {
            FileInputStream fis = context.openFileInput(fileName);//通过Context中的openFileInput(路径)的方法获取输入流
            br = new BufferedReader(new InputStreamReader(fis));
            while((line = br.readLine()) != null){
                sb.append(line);//s +=line;作用一致,但会造成大量的内存浪费
            }
        } catch (IOException e) {//br.readLine()异常块
            e.printStackTrace();
        }
        
        return sb.toString();
    }

}

 

此处用到了JAVA中的I/O流,即输入输出流,小编搜索相应资料如下:

技术分享

想要具体了解的可以通过书籍,网络等资料进行学习.

--------------------------------------------------------------------------------------

需要注意的是,对业务层进行编辑之后需要对业务层中的方法进行单元测试,以确保其正确性.确保业务层内的方法正确后,再进行对控制层(Activity)的编辑,此时,若再出错,则可确定错误不在业务层,去控制层或模型层进行排错即可.

 

单元测试步骤如下:

①在AndroidManifest.xml文件中配置单元测试需要的环境

技术分享

图中,红线内的内容即为所需

②通过继承Android提供的AndroidTestCase父类来编写相应的测试方法

代码如下:

package com.example.savafile.serviceTest;

import com.example.savafile.service.FileService;

import android.test.AndroidTestCase;

/**单元测试*/
public class ServiceTest extends AndroidTestCase {

    /**测试FileService中的save方法*/
    public void testSave() {
        FileService testSave = new FileService(getContext(), "data");//存储为xml文件?
        testSave.save("hello test");
    }
    
    /**测试FileService中的Read方法*/
    public void testRead() {
        FileService testRead = new FileService(getContext(), "data");//存储为xml文件?
        testRead.read();
    }
}

单元测试的方法名最好以    test+需要测试的方法名    命名

③运行测试:

在打开虚拟机(或真机)的情况下,在单元测试类中右击大纲的方法,运行为android项目即可

技术分享

技术分享

测试结果:

技术分享

成功时,红色标记部分会显示绿色进度条,反之,则为红色进度条,且在黄色标记区域显示测试方法的错误信息,非常好用哦

 

步骤3: 控制层编辑:

代码如下:

package com.example.savafile;

import com.example.savafile.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;

/**Android开发遵循的MVC原则  M业务层(FileService)  V(xml布局) C控制层(Activity)
 * 测试业务层,必须要进行单元测试,确定业务层方法没问题的情况下,编写控制层*/
public class MainActivity extends Activity implements OnClickListener {

    private Button btnSvae;
    private EditText etContent;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        initialize();
        readText();
        
    }
    
    /**初始化控件,并设置相应的监听器*/
    private void initialize() {
        btnSvae = (Button) findViewById(R.id.btnSave);
        etContent = (EditText) findViewById(R.id.etContent);
        
        btnSvae.setOnClickListener(this);
    }
    
    /**读取之前存储的数据*/
    private void readText(){
        String data = fileService.read();
        if(data!=null){
            etContent.setText(data);
        }
    }
    
    FileService fileService = new FileService(MainActivity.this, "data.txt"); 
    
    /**监听器方法*/
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btnSave:
            if(fileService.save(etContent.getText().toString())){//是否保存成功
                Toast.makeText(MainActivity.this, "恭喜您,保存成功!", Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(MainActivity.this, "好可惜,保存失败!", Toast.LENGTH_SHORT).show();
            }
            break;

        }
    }

}

到此,就算编辑结束了.谢谢

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。