博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android(二)数据存储和访问 之文件
阅读量:4069 次
发布时间:2019-05-25

本文共 12855 字,大约阅读时间需要 42 分钟。

<p>今日重点内容是Adnroid的数据存储和访问。Android的数据存储有五种:文件</p>
<p>SharedPreferences、SQLite数据库、内容提供者(Content provider)、网络。今天老黎讲解Android的单元测试、文件存储和访问以及解析XML文件。</p>
<p><strong>一、Android的单元测试</strong></p>
<p>昨天进行的只是简单的开发,但从今天起的开发内容比较重要。所以首先应该学习Android的单元测试。在Android工程中添加单元测试的方法:</p>
<p>1.向androidManifest.xml加入:</p>
<p><uses-library android:name="android.test.runner" />,它必须位于<a><application></a>元素体内。是<application>的子元素。</p>
<p><instrumentation android:name="android.test.InstrumentationTestRunner"</p>
<p>android:targetPackage="cn.itcast.action" android:label="Tests for My App" /></p>
<p></application> 与<application>元素并列,是<application>元素的兄弟元素。这里的targetPackage必须是我们创建工程时指定的包名。</p>
<p>2.单元测试类</p>
<p>我们的单元测试类,必须继承自AndroidTestCase类。</p>
<p>3.单元测试方法</p>
<p>单元测试方法必须以test开头</p>
<p>4.方法抛出异常</p>
<p>方法要throws Throwable异常,Throwable是Exception的父类,单元测试框架捕获Throwable。</p>
<p>5.调用测试</p>
<p>在outline面板或方法名上右键,Run AS Android Junit Test。</p>
<p>6.打印信息</p>
<p>在android中不能使用System.out.println()打印信息,但我们可以使用Android为我们提供的Log类来打印信息。可以使用Log.i打开info信息、使用Log.e打印error信息、使用Log.d打印调试信息...。</p>
<p>7.查看打印的信息</p>
<p>因为我们安装了ADT插件,所以选择菜单windows->Show View->Other...->Android->LogCat,打开 LogCat面板。在这个面板中我们可以看到Android输出的所有信息。</p>
<p>但我们只想查看我们自己输出的信息怎么办呢?面板的右上角有个+号,使用它可以创建一个过滤器。比如我们输入一个info信息调用Log.i(tag,”Hello Android!”),tag是信息的标签,一般使用类名。创建过滤器,将Filter Name和by Log Tag都设置为我的们的tag ,OK。它为我们创建了一个新的以tag名称的分页,在这个分页中我们可以查看过滤出来的信息。</p>
<p>在LogCat面板中还有V、D、I、W、E五个选择按钮,从右向左依次包含。比如我们选择D,那么下面的面板将只显示D、I、W这三类信息。</p>
<p><strong>二、Android的文件存储和访问</strong></p>
<p>Android的文件读写与JavaSE的文件读写相同,都是使用IO流。而且Android使用的正是JavaSE的IO流,下面我们通过一个练习来学习Android的文件读写。</p>
<p>1.创建一个Android工程</p>
<p>Project name:FileRW</p>
<p>BuildTarget:Android2.1</p>
<p>Application name:文件读写</p>
<p>Package name:com.changcheng.File</p>
<p>Create Activity:FileRW</p>
<p>Min SDK Version:7</p>
<p>2.编辑strings.xml文件内容:</p>
<p><?xml version=<em>"1.0"</em> encoding=<em>"utf-8"</em>?></p>
<p><resources></p>
<p><string name=<em>"hello"</em>>Hello World, FileRW!</string></p>
<p><string name=<em>"app_name"</em>>文件读写</string></p>
<p><string name=<em>"file_name"</em>>文件名</string></p>
<p><string name=<em>"file_content"</em>>文件内容</string></p>
<p><string name=<em>"button_file_save"</em>>保存</string></p>
<p><string name=<em>"button_file_read"</em>>读取</string></p>
<p><string name=<em>"file_save_success"</em>>保存文件成功</string></p>
<p><string name=<em>"file_save_failed"</em>>保存文件失败</string></p>
<p><string name=<em>"file_read_failed"</em>>读取文件失败</string></p>
<p></resources></p>
<p>3.编辑main.xml文件内容:</p>
<p><?xml version=<em>"1.0"</em> encoding=<em>"utf-8"</em>?></p>
<p><LinearLayout xmlns:android=<em>"http://schemas.android.com/apk/res/android"</em></p>
<p>android:orientation=<em>"vertical"</em> android:layout_width=<em>"fill_parent"</em></p>
<p>android:layout_height=<em>"fill_parent"</em>></p>
<p><!-- 文件名 --></p>
<p><TextView android:layout_width=<em>"fill_parent"</em></p>
<p>android:layout_height=<em>"wrap_content"</em> android:text=<em>"@string/file_name"</em> /></p>
<p><EditText android:layout_width=<em>"fill_parent"</em></p>
<p>android:layout_height=<em>"wrap_content"</em> android:id=<em>"@+id/et_file_name"</em> /></p>
<p><!-- 文件内容 --></p>
<p><TextView android:layout_width=<em>"fill_parent"</em></p>
<p>android:layout_height=<em>"wrap_content"</em> android:text=<em>"@string/file_content"</em> /></p>
<p><EditText android:layout_width=<em>"fill_parent"</em></p>
<p>android:layout_height=<em>"wrap_content"</em> android:minLines=<em>"3"</em></p>
<p>android:id=<em>"@+id/et_file_content"</em> /></p>
<p><!-- 保存和读取按钮,采用相对布局 --></p>
<p><RelativeLayout android:layout_width=<em>"fill_parent"</em></p>
<p>android:layout_height=<em>"wrap_content"</em>></p>
<p><!-- 保存按钮 --></p>
<p><Button android:layout_width=<em>"wrap_content"</em></p>
<p>android:layout_height=<em>"wrap_content"</em> android:text=<em>"@string/button_file_save"</em></p>
<p>android:id=<em>"@+id/bt_save"</em> /></p>
<p><!-- 读取按钮 --></p>
<p><Button android:layout_width=<em>"wrap_content"</em></p>
<p>android:layout_height=<em>"wrap_content"</em> android:layout_toRightOf=<em>"@id/bt_save"</em></p>
<p>android:text=<em>"@string/button_file_read"</em> android:id=<em>"@+id/bt_read"</em> /></p>
<p></RelativeLayout></p>
<p></LinearLayout></p>
<p>4.添加java代码</p>
<p>Android建议采用MVC开发模式,所以我们在Android应用开发中最好使用MVC设计模式。MVC设计模式使三层分离,从而很好的解耦,何乐而不为。</p>
<p>首先我们向工程中添加一个FileService.java:</p>
<p><strong>package</strong> com.changcheng.file.service;</p>
<p><strong>import</strong> java.io.ByteArrayOutputStream;</p>
<p><strong>import</strong> java.io.FileInputStream;</p>
<p><strong>import</strong> java.io.FileOutputStream;</p>
<p><strong>import</strong> android.content.Context;</p>
<p><strong>public</strong> <strong>class</strong> FileService {</p>
<p>Context context;</p>
<p><strong>public</strong> FileService(Context context) {</p>
<p><strong>this</strong>.context = context;</p>
<p>}</p>
<p>/**</p>
<p>* 保存文件</p>
<p>*</p>
<p>* <strong>@param</strong> fileName</p>
<p>* <strong>@param</strong> fileContent</p>
<p>* <strong>@throws</strong> Exception</p>
<p>*/</p>
<p><strong>public</strong> <strong>void</strong> save(String fileName, String fileContent) <strong>throws</strong> Exception {</p>
<p>// Activity的父类的父类就是context,context与其他框架中的context相同为我们以供了一些核心操作工具。</p>
<p>FileOutputStream fileOutputStream = <strong>this</strong>.context.openFileOutput(</p>
<p>fileName, Context.<em>MODE_PRIVATE</em>);</p>
<p>fileOutputStream.write(fileContent.getBytes());</p>
<p>}</p>
<p>/**</p>
<p>* 读取文件</p>
<p>*</p>
<p>* <strong>@param</strong> fileName</p>
<p>* <strong>@return</strong></p>
<p>* <strong>@throws</strong> Exception</p>
<p>*/</p>
<p><strong>public</strong> String read(String fileName) <strong>throws</strong> Exception {</p>
<p>FileInputStream fileInputStream = <strong>this</strong>.context.openFileInput(fileName);</p>
<p>ByteArrayOutputStream byteArray = <strong>new</strong> ByteArrayOutputStream();</p>
<p><strong>byte</strong>[] buffer = <strong>new</strong> <strong>byte</strong>[1024];</p>
<p><strong>int</strong> len = 0;</p>
<p><strong>while</strong> ((len = fileInputStream.read(buffer)) > 0) {</p>
<p>byteArray.write(buffer, 0, len);</p>
<p>};</p>
<p><strong>return</strong> byteArray.toString();</p>
<p>}</p>
<p>}</p>
<p>文件读写的操作模式:</p>
<p>Context.MODE_PRIVATE:新内容覆盖原内容</p>
<p>Context.MODE_APPEND:新内容追加到原内容后</p>
<p>Context.MODE_WORLD_READABLE:允许其他应用程序读取</p>
<p>Context.MODE_WORLD_WRITEABLE:允许其他应用程序写入,会覆盖原数据。</p>
<p>可以使用+连接这些权限。</p>
<p>然后再向工程中添加FileButtonOnClickEvent.java:</p>
<p><strong>package</strong> com.changcheng.file.event;</p>
<p><strong>import</strong> com.changcheng.file.R;</p>
<p><strong>import</strong> com.changcheng.file.service.FileService;</p>
<p><strong>import</strong> android.app.Activity;</p>
<p><strong>import</strong> android.util.Log;</p>
<p><strong>import</strong> android.view.View;</p>
<p><strong>import</strong> android.view.View.OnClickListener;</p>
<p><strong>import</strong> android.widget.Button;</p>
<p><strong>import</strong> android.widget.EditText;</p>
<p><strong>import</strong> android.widget.Toast;</p>
<p>/**</p>
<p>* 按钮事件类</p>
<p>* <strong>@author</strong> Administrator</p>
<p>*</p>
<p>*/</p>
<p><strong>public</strong> <strong>class</strong> FileButtonOnClickEvent <strong>implements</strong> OnClickListener {</p>
<p>// 通过activity获取其他控件</p>
<p><strong>private</strong> Activity activity;</p>
<p>// 通过FileService读写文件</p>
<p><strong>private</strong> FileService fileService;</p>
<p>// 打印信息用的标签</p>
<p><strong>private</strong> <strong>static</strong> <strong>final</strong> String <em>TAG</em> = "FileButtonOnClickEvent";</p>
<p><strong>public</strong> FileButtonOnClickEvent(Activity activity) {</p>
<p><strong>this</strong>.fileService = <strong>new</strong> FileService(activity);</p>
<p><strong>this</strong>.activity = activity;</p>
<p>}</p>
<p>@Override</p>
<p><strong>public</strong> <strong>void</strong> onClick(View v) {</p>
<p>Button button = (Button) v;</p>
<p><strong>switch</strong> (button.getId()) {</p>
<p><strong>case</strong> R.id.<em>bt_save</em>:</p>
<p>// 获取文件名</p>
<p>EditText etFileNameS = (EditText) <strong>this</strong>.activity</p>
<p>.findViewById(R.id.<em>et_file_name</em>);</p>
<p>String fileNameS = etFileNameS.getText().toString();</p>
<p>// 获取文件内容</p>
<p>EditText etFileConS = (EditText) <strong>this</strong>.activity</p>
<p>.findViewById(R.id.<em>et_file_content</em>);</p>
<p>String fileContentS = etFileConS.getText().toString();</p>
<p>// 保存</p>
<p><strong>try</strong> {</p>
<p><strong>this</strong>.fileService.save(fileNameS, fileContentS);</p>
<p>// 在窗口中显示一个特效信息框</p>
<p>Toast.<em>makeText</em>(<strong>this</strong>.activity, R.string.<em>file_save_success</em>,</p>
<p>Toast.<em>LENGTH_LONG</em>).show();</p>
<p>Log.<em>i</em>(<em>TAG</em>, "save file success!");</p>
<p>} <strong>catch</strong> (Exception e) {</p>
<p>Toast.<em>makeText</em>(<strong>this</strong>.activity, R.string.<em>file_save_failed</em>,</p>
<p>Toast.<em>LENGTH_LONG</em>).show();</p>
<p>Log.<em>e</em>(<em>TAG</em>, e.toString());</p>
<p>}</p>
<p><strong>break</strong>;</p>
<p><strong>case</strong> R.id.<em>bt_read</em>:</p>
<p>// 获取文件名</p>
<p>EditText etFileNameR = (EditText) <strong>this</strong>.activity</p>
<p>.findViewById(R.id.<em>et_file_name</em>);</p>
<p>String fileNameR = etFileNameR.getText().toString();</p>
<p>// 读取文件</p>
<p><strong>try</strong> {</p>
<p>String fielContentR = <strong>this</strong>.fileService.read(fileNameR);</p>
<p>EditText etFileConR = (EditText) <strong>this</strong>.activity</p>
<p>.findViewById(R.id.<em>et_file_content</em>);</p>
<p>etFileConR.setText(fielContentR);</p>
<p>Log.<em>i</em>(<em>TAG</em>, "read file success!");</p>
<p>} <strong>catch</strong> (Exception e) {</p>
<p>Toast.<em>makeText</em>(<strong>this</strong>.activity, R.string.<em>file_read_failed</em>,</p>
<p>Toast.<em>LENGTH_LONG</em>).show();</p>
<p>Log.<em>e</em>(<em>TAG</em>, e.toString());</p>
<p>}</p>
<p><strong>break</strong>;</p>
<p><strong>default</strong>:</p>
<p><strong>break</strong>;</p>
<p>}</p>
<p>}</p>
<p>}</p>
<p>最后编辑FileRW.java:</p>
<p><strong>package</strong> com.changcheng.file;</p>
<p><strong>import</strong> com.changcheng.file.event.FileButtonOnClickEvent;</p>
<p><strong>import</strong> android.app.Activity;</p>
<p><strong>import</strong> android.os.Bundle;</p>
<p><strong>import</strong> android.widget.Button;</p>
<p><strong>public</strong> <strong>class</strong> FileRW <strong>extends</strong> Activity {</p>
<p>/** Called when the activity is first created. */</p>
<p>@Override</p>
<p><strong>public</strong> <strong>void</strong> onCreate(Bundle savedInstanceState) {</p>
<p><strong>super</strong>.onCreate(savedInstanceState);</p>
<p>setContentView(R.layout.<em>main</em>);</p>
<p>// 获取所有按钮</p>
<p>Button buttonRead = (Button) <strong>this</strong>.findViewById(R.id.<em>bt_read</em>);</p>
<p>Button buttonSave = (Button) <strong>this</strong>.findViewById(R.id.<em>bt_save</em>);</p>
<p>// 为按钮添加事件</p>
<p>FileButtonOnClickEvent fileBtOnClickEve = <strong>new</strong> FileButtonOnClickEvent(<strong>this</strong>);</p>
<p>buttonRead.setOnClickListener(fileBtOnClickEve);</p>
<p>buttonSave.setOnClickListener(fileBtOnClickEve);</p>
<p>}</p>
<p>}</p>
<p>我们的FileRW.java的可读性是否很好?当然!以后继续改进。但我们的FileService并未使用接口,在JavaEE都使用接口来开发,这样可以实现解耦。由于在Android是手机操作系统平台,如果我们开设的类比较多,会占用系统资源,从而导致系统变慢。所以,尽量的减少接口或类的定义,但也要尽量的做到程序的可读性要好。</p>
<p>在这里我就不演示使用Android的单元测试了,因为它十分容易。我们可以定义一个单元测试类专门用于测试FileService类,Android的测试单元将自动启动模拟器。</p>
<p>5.运行程序</p>
<p>启动模拟器,部署我们的程序。输入文件名和文件内容,点击保存。文件被保存在Android的什么位置?我们知道Android是基于Linux实现的。所以它的根目录是”/”,我们的文件被保存在”/data/data/com.changcheng.file/files”目录下。</p>
<p>我们也可以通过菜单Windows->Show View->Other...->Android->File Explorer,打开 File Explorer面板。通过它可以查看Android的目录结构:</p>
<p>data:应用数据,我们保存的文件在/data/data/packagename/files。</p>
<p>sdcard:现在的手机一般都可以外插一个SD卡,这个目录就是SDCard的目录。操作此目录时需要在主配置文件中注册操作权限。</p>
<p>system:Android操作系统的文件,我们不要修改。</p>
<p>我们可以点击 File Explorer右上角的“软盘向左箭头”图标,导出文件。</p>
<p>6.其他程序获取文件路径的方法</p>
<p>1.绝对路径:/data/data/packagename/files/filename;</p>
<p>2.context:context.getFilesDir()+”/filename”;</p>
<p>缓存目录:/data/data/packagename/Cache或getCacheDir();</p>
<p>如果文件过大就不能存放在手机的文件目录,需要存储到SDCard上。</p>
<p>SDCard目录:/sdcard/或Environment.getExternalStorageDirectory()</p>
<p>使用SDCard目录前,需要判断是否有sdcard:Environment.getExternalStorageState()。操作此目录时需要在主配置文件中注册操作权限。</p>
<p><strong>三、Android的解析XML文件</strong></p>
<p>我们在学习JavaWEB基础时,老方有讲解使用JavaSE解析XML文件。我们在学习JavaEE时一般都使用dom4j解析XML文件。在Android中解析XML与JavaSE和JavaEE都差不多,我们也可以在Andorid中使用dom4j,但这会占用系统的资源。</p>
<p>Andorid中解析XML有三种技术SAX、DOM和pull,重点是Sax和pull。尤其是pull,Android推荐使用,Android系统自身就是使用pull来解析的。pull的解析速度和资源的占用可以与sax相媲美,但使用上比sax更简单。</p>
<p>1.Sax解析XML</p>
<p>Sax是采用事件驱动的方式解析XML文件的,它是流式处理的。什么是流式的?就是从文档首开始流向文档尾,不可倒退。</p>
<p>我们需要编辑一个继承自DefaultHandler的类,因为DefaultHandler实现了ContentHandler接口。关于使用Sax解析XML文件的方式和代码,在此就不做总结了。</p>
<p>2.DOM解析XML</p>
<p>DOM解析XML在我之前的日志中有介绍,在此就不再总结了。</p>
<p>明天继续学习pull解析XML文件!</p>

转载地址:http://hdaji.baihongyu.com/

你可能感兴趣的文章
c# 如何调用win8自带的屏幕键盘(非osk.exe)
查看>>
build/envsetup.sh 简介
查看>>
C++后继有人——D语言
查看>>
Android framework中修改或者添加资源无变化或编译不通过问题详解
查看>>
linux怎么切换到root里面?
查看>>
linux串口操作及设置详解
查看>>
安装alien,DEB与RPM互换
查看>>
linux系统下怎么安装.deb文件?
查看>>
编译Android4.0源码时常见错误及解决办法
查看>>
Android 源码编译make的错误处理
查看>>
linux环境下C语言中sleep的问题
查看>>
ubuntu 12.04 安装 GMA3650驱动
查看>>
新版本的linux如何生成xorg.conf
查看>>
xorg.conf的编写
查看>>
启用SELinux时遇到的问题
查看>>
virbr0 虚拟网卡卸载方法
查看>>
No devices detected. Fatal server error: no screens found
查看>>
新版本的linux如何生成xorg.conf
查看>>
virbr0 虚拟网卡卸载方法
查看>>
Centos 6.0_x86-64 终于成功安装官方显卡驱动
查看>>