Android的数据存储有五种:文件SharedPreferences、SQLite数据库、内容提供者(Content provider)、网络。

一、Android的单元测试

昨天进行的只是简单的开发,但从今天起的开发内容比较重要。所以首先应该学习Android的单元测试。在Android工程中添加单元测试的方法:

1.向androidManifest.xml加入:

<uses-library android:name="android.test.runner" />,它必须位于元素体内。是<application>的子元素。

<instrumentation android:name="android.test.InstrumentationTestRunner"

android:targetPackage="cn.itcast.action" android:label="Tests for My App" />

</application><application>元素并列,是<application>元素的兄弟元素。这里的targetPackage必须是我们创建工程时指定的包名。

2.单元测试类

我们的单元测试类,必须继承自AndroidTestCase类。

3.单元测试方法

单元测试方法必须以test开头

4.方法抛出异常

方法要throws Throwable异常,ThrowableException的父类,单元测试框架捕获Throwable

5.调用测试

outline面板或方法名上右键,Run AS Android Junit Test

6.打印信息

android中不能使用System.out.println()打印信息,但我们可以使用Android为我们提供的Log类来打印信息。可以使用Log.i打开info信息、使用Log.e打印error信息、使用Log.d打印调试信息...

7.查看打印的信息

因为我们安装了ADT插件,所以选择菜单windows->Show View->Other...->Android->LogCat,打开 LogCat面板。在这个面板中我们可以看到Android输出的所有信息。

但我们只想查看我们自己输出的信息怎么办呢?面板的右上角有个+号,使用它可以创建一个过滤器。比如我们输入一个info信息调用Log.i(tag,”Hello Android!”),tag是信息的标签,一般使用类名。创建过滤器,将Filter Name和by Log Tag都设置为我的们的tag ,OK。它为我们创建了一个新的以tag名称的分页,在这个分页中我们可以查看过滤出来的信息。

二、Android的文件存储和访问

Android的文件读写与JavaSE的文件读写相同,都是使用IO流。而且Android使用的正是JavaSEIO流,下面我们通过一个练习来学习Android的文件读写。

Android建议采用MVC开发模式,所以我们在Android应用开发中最好使用MVC设计模式。MVC设计模式使三层分离,从而很好的解耦,何乐而不为。

首先我们向工程中添加一个FileService.java

public class FileService { Context context; public FileService(Context context) { this.context = context; } /** * 保存文件 * * @param fileName * @param fileContent * @throws Exception */ public void save(String fileName, String fileContent) throws Exception { // Activity的父类的父类就是context,context与其他框架中的context相同为我们以供了一些核心操作工具。 FileOutputStream fileOutputStream = this.context.openFileOutput( fileName, Context.MODE_PRIVATE); fileOutputStream.write(fileContent.getBytes()); } /** * 读取文件 * * @param fileName * @return * @throws Exception */ public String read(String fileName) throws Exception { FileInputStream fileInputStream = this.context.openFileInput(fileName); ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while ((len = fileInputStream.read(buffer)) > 0) { byteArray.write(buffer, 0, len); }; return byteArray.toString(); } }

文件读写的操作模式:

Context.MODE_PRIVATE:新内容覆盖原内容

Context.MODE_APPEND:新内容追加到原内容后

Context.MODE_WORLD_READABLE:允许其他应用程序读取

Context.MODE_WORLD_WRITEABLE:允许其他应用程序写入,会覆盖原数据。

可以使用+连接这些权限。

然后再向工程中添加FileButtonOnClickEvent.java: package com.changcheng.file.event; import com.changcheng.file.R; import com.changcheng.file.service.FileService; import android.app.Activity; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; /** * 按钮事件类 * @author Administrator * */ public class FileButtonOnClickEvent implements OnClickListener { // 通过activity获取其他控件 private Activity activity; // 通过FileService读写文件 private FileService fileService; // 打印信息用的标签 private static final String TAG = "FileButtonOnClickEvent"; public FileButtonOnClickEvent(Activity activity) { this.fileService = new FileService(activity); this.activity = activity; } @Override public void onClick(View v) { Button button = (Button) v; switch (button.getId()) { case R.id.bt_save: // 获取文件名 EditText etFileNameS = (EditText) this.activity .findViewById(R.id.et_file_name); String fileNameS = etFileNameS.getText().toString(); // 获取文件内容 EditText etFileConS = (EditText) this.activity .findViewById(R.id.et_file_content); String fileContentS = etFileConS.getText().toString(); // 保存 try { this.fileService.save(fileNameS, fileContentS); // 在窗口中显示一个特效信息框 Toast.makeText(this.activity, R.string.file_save_success, Toast.LENGTH_LONG).show(); Log.i(TAG, "save file success!"); } catch (Exception e) { Toast.makeText(this.activity, R.string.file_save_failed, Toast.LENGTH_LONG).show(); Log.e(TAG, e.toString()); } break; case R.id.bt_read: // 获取文件名 EditText etFileNameR = (EditText) this.activity .findViewById(R.id.et_file_name); String fileNameR = etFileNameR.getText().toString(); // 读取文件 try { String fielContentR = this.fileService.read(fileNameR); EditText etFileConR = (EditText) this.activity .findViewById(R.id.et_file_content); etFileConR.setText(fielContentR); Log.i(TAG, "read file success!"); } catch (Exception e) { Toast.makeText(this.activity, R.string.file_read_failed, Toast.LENGTH_LONG).show(); Log.e(TAG, e.toString()); } break; default: break; } } }

5.运行程序

启动模拟器,部署我们的程序。输入文件名和文件内容,点击保存。文件被保存在Android的什么位置?我们知道Android是基于Linux实现的。所以它的根目录是”/”,我们的文件被保存在”/data/data/com.changcheng.file/files”目录下。

我们也可以通过菜单Windows->Show View->Other...->Android->File Explorer,打开 File Explorer面板。通过它可以查看Android的目录结构:

data:应用数据,我们保存的文件在/data/data/packagename/files。

sdcard:现在的手机一般都可以外插一个SD卡,这个目录就是SDCard的目录。操作此目录时需要在主配置文件中注册操作权限。

systemAndroid操作系统的文件,我们不要修改。

我们可以点击 File Explorer右上角的软盘向左箭头图标,导出文件。

6.其他程序获取文件路径的方法

1.绝对路径:/data/data/packagename/files/filename;

2.context:context.getFilesDir()+”/filename”;

缓存目录:/data/data/packagename/CachegetCacheDir();

如果文件过大就不能存放在手机的文件目录,需要存储到SDCard上。

SDCard目录:/sdcard/Environment.getExternalStorageDirectory()

使用SDCard目录前,需要判断是否有sdcardEnvironment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)

操作此目录时需要在主配置文件中注册操作权限。sdcard里的文件是可以给任何程序访问,与存放在手机卡里是不一样的,因为权限的问题

出处:http://www.blogjava.net/changcheng/archive/2010/02/27/314077.html

openFileOutput()方法的第一参数用于指定文件名称,不能包含路径分隔符“/” ,如果文件不存在,Android 会自动创建它。创建的文件保存在/data/data/<package name>/files目录,如: /data/data/cn.itcast.action/files/itcast.txt ,通过点击Eclipse菜单“Window”-“Show View”-“Other”,在对话窗口中展开android文件夹,选择下面的File Explorer视图,然后在File Explorer视图中展开/data/data/<package name>/files目录就可以看到该文件。

openFileOutput()方法的第二参数用于指定操作模式,有四种模式,分别为: Context.MODE_PRIVATE = 0

Context.MODE_APPEND = 32768

Context.MODE_WORLD_READABLE = 1

Context.MODE_WORLD_WRITEABLE = 2

Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可以使用Context.MODE_APPEND

Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。

Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE用来控制其他应用是否有权限读写该文件。

MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。

如果希望文件被其他应用读和写,可以传入:

openFileOutput("itcast.txt", Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);

android有一套自己的安全模型,当应用程序(.apk)在安装时系统就会分配给他一个userid,当该应用要去访问其他资源比如文件的时候,就需要userid匹配。默认情况下,任何应用创建的文件,sharedpreferences,数据库都应该是私有的(位于/data/data/<package name>/files),其他程序无法访问。除非在创建时指定了Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE ,只有这样其他程序才能正确访问。

如果要打开存放在/data/data/<package name>/files目录应用私有的文件,可以使用Activity提供openFileInput()方法。

FileInputStream inStream = this.getContext().openFileInput("itcast.txt");

Log.i("FileTest", readInStream(inStream));

readInStream()的方法请看本页下面备注。

或者直接使用文件的绝对路径:

File file = new File("/data/data/cn.itcast.action/files/itcast.txt");

FileInputStream inStream = new FileInputStream(file);

Log.i("FileTest", readInStream(inStream));

注意:上面文件路径中的“cn.itcast.action”为应用所在包,当你在编写代码时应替换为你自己应用使用的包。

对于私有文件只能被创建该文件的应用访问,如果希望文件能被其他应用读和写,可以在创建文件时,指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE权限。

如果需要读和写的方法,则要吧两者使用加号合并权限

Activity还提供了getCacheDir()和getFilesDir()方法:

getCacheDir()方法用于获取/data/data/<package name>/cache目录

getFilesDir () 方法用于获取 /data/data/<package name>/files 目录

更多相关文章

  1. Android夸进程通信机制五:使用文件共享进行进程间通信
  2. Android保存数据几种常用方法解析
  3. 初涉Android之文件保存
  4. Android Studio Gradle 添加.so 支持文件
  5. 在Android设备与Mac电脑之间传输文件
  6. Android 中插件的编写方法
  7. Android shape方法绘制图形的方法和属性解析

随机推荐

  1. android 比较符合android构架,优雅的定义
  2. Android快速开发
  3. Using your own SQLite database in Andr
  4. android 登录判断
  5. android之单选框
  6. Android(安卓)tensorflow图片识别demo
  7. Android——SimpleExpandableListAdapter
  8. Android:View的getLocalVisibleRect()和getG
  9. android 版本跟新之下载
  10. Android(安卓)双缓冲 使用 示例