Android 常见的数据存储方式

来源:互联网 发布:微信正在修复数据库 编辑:程序博客网 时间:2024/06/07 00:56


1.SharedPreferences存储

首先SharedPreferences比较适合关系简单的数据存储,比如存储键值对。存储数据:

private static final String FILENAME = "filename";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);SharedPreferences share = super.getSharedPreferences(FILENAME,Activity.MODE_PRIVATE);SharedPreferences.Editor edit = share.edit(); edit.putString("author", "zhoumushui") ;edit.putInt("age", 22);edit.commit() ;

读取数据:

private static final String FILENAME = "filename";// 文件名称 private TextView authorInfo = null ;// 文本显示private TextView ageInfo = null ;// 文本显示@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);super.setContentView(R.layout.main) ;// 定义布局管理器this.authorInfo = (TextView) super.findViewById(R.id.authorinfo) ;this.ageInfo = (TextView) super.findViewById(R.id.ageinfo) ;SharedPreferences share = super.getSharedPreferences(FILENAME,Activity.MODE_PRIVATE);// 指定操作的文件名称this.authorInfo.setText("作者:" + share.getString("author", "没有作者信息。"));this.ageInfo.setText("年龄:" + share.getInt("age", 0));}

其实前面九宫格手势密码的项目就用到了SharedPreferences,可以参考一下


2.文件存储

SharedPreferences比较简单就不多说了,下面看一下文件的:

首先是存储文件:

private static final String FILENAME = "zhou.txt" ;// 设置文件名称@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);super.setContentView(R.layout.main);// 调用布局文件        FileOutputStream output = null ;// 文件输出流try {// 设置输出的文件名称,及文件创建模式output = super.openFileOutput(FILENAME, Activity.MODE_PRIVATE);} catch (FileNotFoundException e) {e.printStackTrace();}        PrintStream out = new PrintStream(output) ;// 打印流包装        out.println("ZHOU");// 输出数据        out.println("MU") ;         out.println("SHUI") ;        out.close() ;// 关闭输出流}

接着读取文件:

private static final String FILENAME = "zhou.txt" ;// 设置文件名称private TextView msg = null ;// 文本组件@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);super.setContentView(R.layout.main);// 调用布局文件this.msg = (TextView) super.findViewById(R.id.msg) ;        FileInputStream input = null;// 文件输入流try {// 找到指定文件的输入流对象input = super.openFileInput(FILENAME);} catch (FileNotFoundException e) {e.printStackTrace();}        Scanner scan = new Scanner(input) ;// 定义Scanner        while(scan.hasNext()){// 循环读取        this.msg.append(scan.next() + "\n") ;// 设置文本        }        scan.close() ;// 关闭输入流}

这样就可以实现一些基本的文件操作,目前还没有写关于文件操作比较复杂的Demo,想深入了解的朋友可以看一下GitHub上小米的“MIUI文件管理器社区开源版“。

今天就先这样,去学习了。


3.JSON数据的解析与封装

今天早早的下班了,写了一个简单的JSON Demo,这里总结一下。

首先是效果图:


简单起见,解析部分并没有采用解析URL的方式,直接把JSON写到String里,逻辑比较简单,这里就不啰嗦了,上代码:

package com.example.jsondemo;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import android.app.Activity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;public class Main extends Activity {// private static final String BASE_URL =// "http://zhoumushui.sinaapp.com/json/";private TextView tvMsg;private TextView tvJson;private EditText etName;private EditText etAge;private String strJson = "";private String staffInfo = "";private String strJsonRes = "";private String strMsg;private Button btnAdd;private Button btnJson;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);tvMsg = (TextView) findViewById(R.id.tvMsg);tvJson = (TextView) findViewById(R.id.tvJson);etName = (EditText) findViewById(R.id.etName);etAge = (EditText) findViewById(R.id.etAge);btnAdd = (Button) findViewById(R.id.btnAdd);btnJson = (Button) findViewById(R.id.btnJson);MsgToJson(); // 封装JsonJsonToMsg(); // 解析Json}class onClickListenerImp implements OnClickListener {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif (v == btnAdd) {if (strMsg != null && strJson.trim().length() != 0) {strMsg = strMsg + ",{name:'" + etName.getText().toString()+ "',age:" + etAge.getText().toString() + "}";} else {strMsg = "{staff:[{name:'" + etName.getText().toString()+ "',age:" + etAge.getText().toString() + "}";}Toast.makeText(Main.this, "Add Succcess!", Toast.LENGTH_SHORT).show();etAge.setText("");etName.setText("");} else if (v == btnJson) {strJsonRes = "";strJsonRes = strMsg + "]}";tvJson.setText(strJsonRes);}}}private void MsgToJson() {btnAdd.setOnClickListener(new onClickListenerImp());btnJson.setOnClickListener(new onClickListenerImp());}private void JsonToMsg() {strJson = "{staff:[{name:'Alex',age:21},{name:'Zhou',age:22},{name:'Anne',age:23}],company:'T-Chip'}";staffInfo = "原始数据:\n" + strJson + "\n\n解析之后:\n";try {JSONObject mJsonObject = new JSONObject(strJson);JSONArray mJsonArray = mJsonObject.getJSONArray("staff");String company = mJsonObject.getString("company");staffInfo = staffInfo + company + "共有 " + mJsonArray.length()+ " 个员工,信息如下:\n";for (int staffCount = 0; staffCount < mJsonArray.length(); staffCount++) {// 获取员工JSONObject staff = mJsonArray.getJSONObject(staffCount);int staffNo = staffCount + 1;staffInfo = staffInfo + "序号:" + staffNo + "  姓名: "+ staff.getString("name") + "  年龄: "+ staff.getInt("age") + "\n";}tvMsg.setText(staffInfo);} catch (JSONException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}}


布局有点拖沓,其实数据封装部分还可以利用一下解析部分的逻辑。

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <TextView        android:id="@+id/tvMsg"        android:layout_width="fill_parent"        android:layout_height="wrap_content" />    <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="==========================" />    <LinearLayout        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:orientation="horizontal" >        <EditText            android:id="@+id/etName"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:hint="姓名" />        <EditText            android:id="@+id/etAge"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:hint="年龄" />        <Button            android:id="@+id/btnAdd"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="增加" />          <Button            android:id="@+id/btnJson"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="JSON" />            </LinearLayout>    <TextView        android:id="@+id/tvJson"        android:layout_width="fill_parent"        android:layout_height="wrap_content" /></LinearLayout>


4.DOM,SAX解析XML

分别通过DOM和SAX解析XML实现存储和读取XML信息。

首先是DOM存储信息到XML文件:

// 判断是否存在SDCardif(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){return ;}// 路径:/sdcard/zhoumushui/android.xmlFile file = new File(Environment.getExternalStorageDirectory().toString()+ File.separator+ "zhoumushui" + File.separator + "android.xml") ;// 若目录不存在则创建if (! file.getParentFile().exists()) {file.getParentFile().mkdirs() ; }DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = null;try {builder = factory.newDocumentBuilder();} catch (ParserConfigurationException e) {e.printStackTrace();}Document doc = null;doc = builder.newDocument();// 根标签Element roottag = doc.createElement("roottag") ;// 次标签Element infotag = doc.createElement("infotag") ;Element name = doc.createElement("name") ;Element url = doc.createElement("url") ;name.appendChild(doc.createTextNode(MyDOMDemo.this.name.getText().toString())); url.appendChild(doc.createTextNode(MyDOMDemo.this.url.getText().toString())) ;// 次标签有两个子元素name和urlinfotag.appendChild(name) ;infotag.appendChild(url) ;// 主标签有一个子元素infotagroottag.appendChild(infotag) ;doc.appendChild(roottag) ;TransformerFactory transformerFactory = TransformerFactory.newInstance();Transformer transformer = null;try {transformer = transformerFactory.newTransformer();} catch (TransformerConfigurationException e1) {e1.printStackTrace();}transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8") ;// 定义source和result,从source变形为result:DOMSource source = new DOMSource(doc);StreamResult result = new StreamResult(file);try {transformer.transform(source, result);} catch (TransformerException e) {e.printStackTrace();}

在Activity中输入内容后,点击Button提交后,在/sdcard/zhoumushui/android.xml文件中显示以下信息:

<?xml version="1.0" encoding="UTF-8"?><roottag><infotag><name>zhoumushui</name><url>blog.csdn.net/zhoumushui</url></infotag></roottag>

成功实现了将数据存储到XML文件中,下面看一下怎么用DOM读取XML中的信息:

if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {return;}File file = new File(Environment.getExternalStorageDirectory().toString()+ File.separator+ "zhoumushui"+ File.separator + "android.xml");if (!file.exists()) {return;}// 建立DocumentBuilderFactory,以用于取得DocumentBuilderDocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 通过DocumentBuilderFactory取得DocumentBuilderDocumentBuilder builder = null;try {builder = factory.newDocumentBuilder();} catch (ParserConfigurationException e) {e.printStackTrace();}// 定义Document接口对象,通过DocumentBuilder类进行DOM树的转换操作Document doc = null;try {doc = builder.parse(file); // 读取指定路径的xml文件} catch (SAXException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}NodeList nodeList = doc.getElementsByTagName("infotag");// 输出NodeList中第一个子节点中文本节点的内容for (int x = 0; x < nodeList.getLength(); x++) { // 循环输出节点内容Element e = (Element) nodeList.item(x); // 取得每一个元素MyDOMDemo.this.name.setText(e.getElementsByTagName("name").item(0).getFirstChild().getNodeValue()); // 设置文本MyDOMDemo.this.email.setText(e.getElementsByTagName("url").item(0).getFirstChild().getNodeValue()); // 设置文本}

这样就可以读取到刚刚存储到android.xml文件中的内容了。

下面看一下另外一种解析方式SAX获得xml中内容的处理方法:

Activity中的内容与DOM类似:

if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {return;}File file = new File(Environment.getExternalStorageDirectory().toString()+ File.separator+ "zhoumushui"+ File.separator + "android.xml");if (!file.exists()) {return;}SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = null;MySAX mySax = new MySAX();try {parser = factory.newSAXParser();} catch (Exception e) {e.printStackTrace();}try {parser.parse(file, mySax);} catch (Exception e) {e.printStackTrace();}List<LinkMan> all = mySax.getAll();name.setText(all.get(0).getName());url.setText(all.get(0).getUrl());

MySAX类继承自org.xml.sax.helpers.DefaultHandler :

public class MySAX extends DefaultHandler {private List<LinkMan> all = null;private String elementName = null;private LinkMan linkMan = null;@Overridepublic void startDocument() throws SAXException {this.all = new ArrayList<LinkMan>();}@Overridepublic void startElement(String uri, String localName, String name,Attributes attributes) throws SAXException {if ("infotag".equals(localName)) {this.linkMan = new LinkMan();}this.elementName = localName;}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {if (this.elementName != null) {String data = new String(ch, start, length);if ("name".equals(this.elementName)) {this.linkMan.setName(data);} else if ("url".equals(this.elementName)) {this.linkMan.setUrl(data);}}}@Overridepublic void endElement(String uri, String localName, String name)throws SAXException {if ("linkman".equals(localName)) {this.all.add(this.linkMan);this.linkMan = null;}this.elementName = null;}public List<LinkMan> getAll() {return this.all;}}

这两天开始开始忙起来了,做一些mediaTek编译和固件的事情,还有Qualcomm的初步熟悉和部分源码了解。今晚还要赶一下月度述职报告,就先这样了。


5.初识Media类的EXTERNAL_CONTENT_URI和INTERNAL_CONTENT_URI

今天有个客户需求,要内置一个不可删除的视频。

不可删除的话,不能在设备中删除,USB连接电脑也不能删除。那么直接放到system/media/下好了,这样对用户就完全不可见了,这样还不行,完全不可见,就失去了内置视频的意义,所以我们还要在视频播放器中显示出来,这就要修改播放器的源码,让播放器读取Internal的媒体文件即可。


adb shell,查看如下目录

/data/data/com.android.providers.media/databases/

可以看到有两个数据库文件:external.db和internal.db:




分别打开可以看到:


其中External为sdcard下的多媒体文件,Internal为system下的多媒体文件。

对应的CONTENT_URI:

Media.EXTERNAL_CONTENT_URI
Media.INTERNAL_CONTENT_URI



转载请注明出处:周木水的CSDN博客 http://blog.csdn.net/zhoumushui


0 0
原创粉丝点击