首页 > 代码库 > 16_Android的数据存储_ SharedPreference、XML和JSON

16_Android的数据存储_ SharedPreference、XML和JSON

1. Android读写首选项

1.1 SharedPreferences

  SharedPreferences 是一种轻型的数据存储方式,它的本质是基于XML文件存储Key-Value键值对数据,通常用来存储一些简单的配置信息,其存储位置在/data/data/<包名>/shared_prefs目录下。

  SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。本例程讲解 SharedPreference 数据的读写操作。

 1 package com.example.sharedpreference; 2  3 import android.app.Activity; 4 import android.content.SharedPreferences; 5 import android.content.SharedPreferences.Editor; 6 import android.os.Bundle; 7 import android.view.View; 8 import android.widget.EditText; 9 import android.widget.Toast;10 11 public class MainActivity extends Activity {12     13     static final String KEY = "MyValue";14     private EditText et;15     SharedPreferences preferences;16     Editor editor;17 18     @Override19     protected void onCreate(Bundle savedInstanceState) {20         super.onCreate(savedInstanceState);21         setContentView(R.layout.activity_main);22 23         et = (EditText) findViewById(R.id.et);24         preferences = getPreferences(Activity.MODE_PRIVATE);25         editor = preferences.edit();26         27         findViewById(R.id.btnRead).setOnClickListener(new View.OnClickListener() {28             29             @Override30             public void onClick(View v) {31                 //如果键值对不存在,就会将其改为第二个参数。32                 String in = preferences.getString(KEY, "当前数值不存在");33                 Toast.makeText(getApplicationContext(), in, Toast.LENGTH_SHORT).show();34             }35         });36         37         findViewById(R.id.btnWrite).setOnClickListener(new View.OnClickListener() {38             39             @Override40             public void onClick(View v) {41                 editor.putString(KEY, et.getText().toString());42                 if (editor.commit()) {43                     Toast.makeText(getApplicationContext(), "写入成功", Toast.LENGTH_SHORT).show();44                 }45             }46         });47     }48 49 }
MainActivity
 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2     xmlns:tools="http://schemas.android.com/tools" 3     android:id="@+id/container" 4     android:layout_width="match_parent" 5     android:layout_height="match_parent" 6     android:orientation="vertical" 7     tools:context="com.example.sharedpreference.MainActivity" 8     tools:ignore="MergeRootFrame" > 9 10     <EditText11         android:id="@+id/et"12         android:layout_width="fill_parent"13         android:layout_height="wrap_content"14         android:ems="10" >15 16         <requestFocus />17     </EditText>18 19     <Button20         android:id="@+id/btnRead"21         android:layout_width="fill_parent"22         android:layout_height="wrap_content"23         android:text="读取数据" />24 25     <Button26         android:id="@+id/btnWrite"27         android:layout_width="fill_parent"28         android:layout_height="wrap_content"29         android:text="写入数据" />30 31 </LinearLayout>
activity_main.xml

1.2 SharedPreference

  SharedPreference是纯操作,如果需要配合界面的话,则需要额外的开发,PreferenceActivity提供了一种快速创建配置首选项界面的方法,并且自动在后台存储首选项数据。

 1 package com.example.preferenceactivity; 2  3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.view.View; 7  8 public class MainActivity extends Activity { 9 10     @Override11     protected void onCreate(Bundle savedInstanceState) {12         super.onCreate(savedInstanceState);13         setContentView(R.layout.activity_main);14 15         findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {16 17             @Override18             public void onClick(View v) {19                 startActivity(new Intent(getApplicationContext(),20                         MyPreferenceActivity.class));21             }22         });23     }24 25 }
MainActivity
 1 package com.example.preferenceactivity; 2  3 import android.os.Bundle; 4 import android.preference.CheckBoxPreference; 5 import android.preference.EditTextPreference; 6 import android.preference.ListPreference; 7 import android.preference.PreferenceActivity; 8 import android.preference.PreferenceManager; 9 import android.widget.Toast;10 11 public class MyPreferenceActivity extends PreferenceActivity{12 13     //checkboxPreference14     //listPreference15     //edittextPreference16     17     PreferenceManager manager;18     CheckBoxPreference checkBoxPreference;19     ListPreference listPreference;20     EditTextPreference editTextPreference;21     22     @Override23     protected void onCreate(Bundle savedInstanceState) {24         super.onCreate(savedInstanceState);25         addPreferencesFromResource(R.xml.myprefrence);26         27         manager = getPreferenceManager();28         checkBoxPreference = (CheckBoxPreference) manager.findPreference("checkbox");29         Toast.makeText(getApplicationContext(), "当前的状态为:" + checkBoxPreference.isChecked(), Toast.LENGTH_SHORT).show();30         31         listPreference = (ListPreference) manager.findPreference("list");32         Toast.makeText(getApplicationContext(), "当前的状态为:" + listPreference.getValue() + "\n开发环境为:" + listPreference.getEntry(), Toast.LENGTH_SHORT).show();33         34         editTextPreference = (EditTextPreference) manager.findPreference("text");35         Toast.makeText(getApplicationContext(), "你输入的内容为:" + editTextPreference.getText(), Toast.LENGTH_SHORT).show();36     }37 }
MyPreferenceActivity
 1 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 2     xmlns:tools="http://schemas.android.com/tools" 3     android:id="@+id/container" 4     android:layout_width="match_parent" 5     android:layout_height="match_parent" 6     tools:context="com.example.preferenceactivity.MainActivity" 7     tools:ignore="MergeRootFrame" > 8  9     <Button10         android:id="@+id/btn"11         android:layout_width="fill_parent"12         android:layout_height="wrap_content"13         android:text="修改首选项" />14 15 </FrameLayout>
activity_main.xml
 1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3  4     <string-array name="entries"> 5         <item>Java</item> 6         <item>Swift</item> 7         <item>C#</item> 8     </string-array> 9     <string-array name="values">10         <item>Eclips</item>11         <item>Xcode</item>12         <item>Visual Studio</item>13     </string-array>14 15 </resources>
mylistpreference.xml(values文件中)

2. SQLite数据库的数据读取和写入

  1 package com.example.usingsqlite;  2   3 import android.app.ListActivity;  4 import android.content.ContentValues;  5 import android.database.Cursor;  6 import android.database.sqlite.SQLiteDatabase;  7 import android.os.Bundle;  8 import android.support.v4.widget.SimpleCursorAdapter;  9 import android.view.View; 10 import android.widget.Button; 11 import android.widget.EditText; 12  13 public class MainActivity extends ListActivity { 14  15     private SimpleCursorAdapter adapter; 16     private EditText etName, etSex; 17     private Button btnAdd; 18     private Db db; 19     private SQLiteDatabase dbRead, dbWrite; 20  21     @Override 22     protected void onCreate(Bundle savedInstanceState) { 23         super.onCreate(savedInstanceState); 24         setContentView(R.layout.activity_main); 25  26         etName = (EditText) findViewById(R.id.etName); 27         etSex = (EditText) findViewById(R.id.etSex); 28         btnAdd = (Button) findViewById(R.id.btnAdd); 29  30         btnAdd.setOnClickListener(new View.OnClickListener() { 31  32             @Override 33             public void onClick(View v) { 34                 ContentValues cv = new ContentValues(); 35                 cv.put("name", etName.getText().toString()); 36                 cv.put("sex", etSex.getText().toString()); 37  38                 dbWrite.insert("user", null, cv); 39                 refreshListView(); 40             } 41         }); 42  43         // getListView().setOnItemLongClickListener(new 44         // OnItemLongClickListener() { 45         // 46         // @Override 47         // public boolean onItemLongClick(AdapterView<?> parent, View view, 48         // final int position, long id) { 49         // 50         // Cursor c = adapter.getCursor(); 51         // c.moveToPosition(position); 52         // 53         // //在数据库中的ID 54         // int itemId = c.getInt(c.getColumnIndex("_id")); 55         // dbWrite.delete("user", "_id=?", new String[]{itemId+""}); 56         // refreshListView(); 57         // 58         // 59         // // new 60         // AlertDialog.Builder(MainActivity.this).setTitle("提醒").setMessage("您确定要删除该项吗?").setNegativeButton("取消", 61         // null).setPositiveButton("确定", new DialogInterface.OnClickListener() { 62         // // 63         // // @Override 64         // // public void onClick(DialogInterface dialog, int which) { 65         // // 66         // // } 67         // // }).show(); 68         // 69         // 70         // return true; 71         // } 72         // }); 73  74         Db db = new Db(this); 75         dbRead = db.getReadableDatabase(); 76         dbWrite = db.getWritableDatabase(); 77  78         adapter = new SimpleCursorAdapter(this, R.layout.user_list_cell, null, 79                 new String[] { "name", "sex" }, new int[] { R.id.tvName, 80                         R.id.tvSex }); 81         setListAdapter(adapter); 82  83         refreshListView(); 84  85         // Db db = new Db(this); 86         // //写入几条元素 87         // SQLiteDatabase dbWrite = db.getWritableDatabase(); 88         // ContentValues cv = new ContentValues(); 89         // cv.put("name", "小张"); 90         // cv.put("sex", "男"); 91         // dbWrite.insert("user", null, cv); 92         // 93         // cv = new ContentValues(); 94         // cv.put("name", "小红"); 95         // cv.put("sex", "女"); 96         // dbWrite.insert("user", null, cv); 97         // dbWrite.close(); 98         // 99         // SQLiteDatabase dbRead = db.getReadableDatabase();100         // Cursor c = dbRead.query("user", null, null, null, null,null, null);101         //102         // while (c.moveToNext()) {103         // String name = c.getString(c.getColumnIndex("name"));104         // String sex = c.getString(c.getColumnIndex("sex"));105         // System.out.println(String.format("name = %s  sex = %s", name, sex));106         // }107     }108 109     private void refreshListView() {110         Cursor c = dbRead.query("user", null, null, null, null, null, null);111         adapter.changeCursor(c);112     }113 114 }
MainActivity
 1 package com.example.usingsqlite; 2  3 import android.content.Context; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.database.sqlite.SQLiteOpenHelper; 6  7 public class Db extends SQLiteOpenHelper { 8  9     public Db(Context context) {10         // 第四个变量是版本,onUpgrade11         super(context, "db", null, 1);12 13     }14 15     @Override16     public void onCreate(SQLiteDatabase db) {17         // 创建了一个用户表18         db.execSQL("CREAT TABLE user("19                 + "_id INTEGER PRIMARY KEY AUTOINCREMENT,"20                 + "name TEXT DEFAULT \"\"," + "sex TEXT DEFAULT \"\")");21     }22 23     @Override24     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {25         // TODO Auto-generated method stub26 27     }28 29 }
Db 

3. 操作XML数据

  XML,即可扩展标记语言(Extensible Markup Language,标准通用标记语言的子集,一种用于标记电子文件使其具有结构性的标记语言。它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。

3.1 读取与解析XML数据

  使用Android平台自带的API加载XML数据,并且按照XML的结构将所有数据解析出来。

 1 package com.example.textxml; 2  3 import java.io.IOException; 4 import javax.xml.parsers.DocumentBuilder; 5 import javax.xml.parsers.DocumentBuilderFactory; 6 import javax.xml.parsers.ParserConfigurationException; 7 import org.w3c.dom.Document; 8 import org.w3c.dom.Element; 9 import org.w3c.dom.NodeList;10 import org.xml.sax.SAXException;11 12 import android.app.Activity;13 import android.os.Bundle;14 import android.widget.TextView;15 16 public class MainActivity extends Activity {17     18     TextView text;19 20     @Override21     protected void onCreate(Bundle savedInstanceState) {22         super.onCreate(savedInstanceState);23         setContentView(R.layout.activity_main);24         text = (TextView) findViewById(R.id.text);25         26         try {27             28             DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();29             DocumentBuilder builder = builderFactory.newDocumentBuilder();30             Document document = builder.parse(getAssets().open("languages.xml"));31             //获取根元素32             Element element = document.getDocumentElement();33             NodeList list = element.getElementsByTagName("lan");34             for (int i = 0; i < list.getLength(); i++) {35                 Element lan = (Element) list.item(i);36                 text.append(lan.getAttribute("id") + "\n");37                 text.append(lan.getElementsByTagName("name").item(0).getTextContent() + "\n");38                 text.append(lan.getElementsByTagName("ide").item(0).getTextContent() + "\n");39             }40             41         } catch (ParserConfigurationException e) {42             e.printStackTrace();43         } catch (SAXException e) {44             // TODO Auto-generated catch block45             e.printStackTrace();46         } catch (IOException e) {47             // TODO Auto-generated catch block48             e.printStackTrace();49         }50     }51 }
MainActivity
 1 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 2     xmlns:tools="http://schemas.android.com/tools" 3     android:id="@+id/container" 4     android:layout_width="match_parent" 5     android:layout_height="match_parent" 6     tools:context="com.example.textxml.MainActivity" 7     tools:ignore="MergeRootFrame" > 8  9     <TextView10         android:id="@+id/text"11         android:layout_width="fill_parent"12         android:layout_height="fill_parent"13         android:text="ready" />14 15 </FrameLayout>
activity_main.xml

  assets文件夹中的languages.xml文件的内容:

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <Languages cat="it"> 3     <lan id="1"> 4         <name>Java</name> 5         <ide>Eclipse</ide> 6     </lan> 7     <lan id="2"> 8         <name>Swift</name> 9         <ide>Xcode</ide>10     </lan>11     <lan id="3">12         <name>C#</name>13         <ide>Visual Studio</ide>14     </lan>15 </Languages>
language.xml

3.2 生成与输出XML数据

  使用Android平台自带的API创建符合XML规范的数据,并且将XML数据输出。

 1 package com.example.textxml; 2  3 import java.io.StringWriter; 4  5 import javax.xml.parsers.DocumentBuilder; 6 import javax.xml.parsers.DocumentBuilderFactory; 7 import javax.xml.parsers.ParserConfigurationException; 8 import javax.xml.transform.Transformer; 9 import javax.xml.transform.TransformerConfigurationException;10 import javax.xml.transform.TransformerException;11 import javax.xml.transform.TransformerFactory;12 import javax.xml.transform.dom.DOMSource;13 import javax.xml.transform.stream.StreamResult;14 15 import org.w3c.dom.Document;16 import org.w3c.dom.Element;17 import android.app.Activity;18 import android.os.Bundle;19 import android.widget.TextView;20 21 public class MainActivity extends Activity {22 23     TextView text;24 25     @Override26     protected void onCreate(Bundle savedInstanceState) {27         super.onCreate(savedInstanceState);28         setContentView(R.layout.activity_main);29         text = (TextView) findViewById(R.id.text);30 31         try {32 33             DocumentBuilderFactory builderFactory = DocumentBuilderFactory34                     .newInstance();35             DocumentBuilder builder = builderFactory.newDocumentBuilder();36             // Document document =37             // builder.parse(getAssets().open("languages.xml"));38             // //获取根元素39             // Element element = document.getDocumentElement();40             // NodeList list = element.getElementsByTagName("lan");41             // for (int i = 0; i < list.getLength(); i++) {42             // Element lan = (Element) list.item(i);43             // text.append(lan.getAttribute("id") + "\n");44             // text.append(lan.getElementsByTagName("name").item(0).getTextContent() + "\n");45             // text.append(lan.getElementsByTagName("ide").item(0).getTextContent() + "\n");46             // }47 48             Document newxml = builder.newDocument();49             Element languages = newxml.createElement("Languages");50             languages.setAttribute("cat", "it");51 52             Element lan1 = newxml.createElement("lan");53             lan1.setAttribute("id", "1");54             Element name1 = newxml.createElement("name");55             name1.setTextContent("Java");56             Element ide1 = newxml.createElement("ide");57             name1.setTextContent("Eclipse");58             lan1.appendChild(name1);59             lan1.appendChild(ide1);60             languages.appendChild(lan1);61 62             Element lan2 = newxml.createElement("lan");63             lan2.setAttribute("id", "2");64             Element name2 = newxml.createElement("name");65             name1.setTextContent("Swift");66             Element ide2 = newxml.createElement("ide");67             name1.setTextContent("Xcode");68             lan1.appendChild(name2);69             lan1.appendChild(ide2);70             languages.appendChild(lan2);71 72             newxml.appendChild(languages);73 74             TransformerFactory transformerFactory = TransformerFactory75                     .newInstance();76             Transformer transformer = transformerFactory.newTransformer();77             transformer.setOutputProperty("encoding", "UTF-8");78             StringWriter sw = new StringWriter();79             transformer.transform(new DOMSource(newxml), new StreamResult(sw));80 81             text.setText(sw.toString());82 83         } catch (ParserConfigurationException e) {84             e.printStackTrace();85         } catch (TransformerConfigurationException e) {86             // TODO Auto-generated catch block87             e.printStackTrace();88         } catch (TransformerException e) {89             // TODO Auto-generated catch block90             e.printStackTrace();91         }92     }93 }
MainActivity 

4. 操作JSON数据

  JSONJavaScript 对象表示法(JavaScript Object Notation)。独立于语言和平台,比 XML 更小、更快,更易解析。

4.1 JSON(JavaScript Object Notation) 定义:

  一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。业内主流技术为其提供了完整的解决方案(有点类似于正则表达式,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换。JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为。 Json.org

4.2 JSON的结构:

  (1) Name/Value Pairs(无序的):类似所熟知的Keyed list Hash tableDisctionaryAssociative array。在Android平台中同时存在另外一个类 "Bundle",某种程度上具有相似的行为。

  (2) Array(有序的):一组有序的数据列表。

  对象是一个无序的Name/Value Pairs集合。{ name:value , name:value , name:value .... }

  例子:{ "name":"小猪","age":20 }

4.3读取JSON格式数据

  Android平台自带了JSON解析的相关API,可以将文件、输入流中的数据转化为JSON对象,然后从对象中获取JSON保存的数据内容。下图是logcat中的内容。

 1 package com.example.testjson; 2  3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.io.UnsupportedEncodingException; 7  8 import org.json.JSONArray; 9 import org.json.JSONException;10 import org.json.JSONObject;11 12 import android.app.Activity;13 import android.os.Bundle;14 15 public class MainActivity extends Activity {16 17     @Override18     protected void onCreate(Bundle savedInstanceState) {19         super.onCreate(savedInstanceState);20         setContentView(R.layout.activity_main);21 22         try {23             InputStreamReader isr = new InputStreamReader(getAssets().open(24                     "test.json"), "UTF-8");25             BufferedReader br = new BufferedReader(isr);26             String line;27             StringBuilder builder = new StringBuilder();28             while ((line = br.readLine()) != null) {29                 builder.append(line);30             }31             br.close();32             isr.close();33             JSONObject root = new JSONObject(builder.toString());34             System.out.println("cat=" + root.getString("cat"));35             JSONArray array = root.getJSONArray("languages");36             for (int i = 0; i < array.length(); i++) {37                 JSONObject lan = array.getJSONObject(i);38                 System.out.println("-----------------------");39                 System.out.println("id=" + lan.getInt("id"));40                 System.out.println("name=" + lan.getString("name"));41                 System.out.println("ide=" + lan.getString("ide"));42             }43 44         } catch (UnsupportedEncodingException e) {45             e.printStackTrace();46         } catch (IOException e) {47             e.printStackTrace();48         } catch (JSONException e) {49             e.printStackTrace();50         }51 52     }53 54 }
MainActivity

   assets文件夹中test.json文件的内容:

1 {2     "languages":[3         {"id":1,"ide":"Eclipse","name":"Java"},4         {"id":2,"ide":"Xcode","name":"Swift"},5         {"id":3,"ide":"Visual Studio","name":"C#"}6     ],7     "cat":"it"8 }
test.json

4.4创建JSON格式数据

  Android平台自带了JSON构造的相关API,可以轻松地构造JSON对象、JSON数组,并且为他们赋值,而且很容易将JSON对象转换为字符串用于传播。

 1 package com.example.testjson; 2  3 import org.json.JSONArray; 4 import org.json.JSONException; 5 import org.json.JSONObject; 6  7 import android.app.Activity; 8 import android.os.Bundle; 9 10 public class MainActivity extends Activity {11 12     @Override13     protected void onCreate(Bundle savedInstanceState) {14         super.onCreate(savedInstanceState);15         setContentView(R.layout.activity_main);16 17 //        try {18 //            InputStreamReader isr = new InputStreamReader(getAssets().open(19 //                    "test.json"), "UTF-8");20 //            BufferedReader br = new BufferedReader(isr);21 //            String line;22 //            StringBuilder builder = new StringBuilder();23 //            while ((line = br.readLine()) != null) {24 //                builder.append(line);25 //            }26 //            br.close();27 //            isr.close();28 //            JSONObject root = new JSONObject(builder.toString());29 //            System.out.println("cat=" + root.getString("cat"));30 //            JSONArray array = root.getJSONArray("languages");31 //            for (int i = 0; i < array.length(); i++) {32 //                JSONObject lan = array.getJSONObject(i);33 //                System.out.println("-----------------------");34 //                System.out.println("id=" + lan.getInt("id"));35 //                System.out.println("name=" + lan.getString("name"));36 //                System.out.println("ide=" + lan.getString("ide"));37 //            }38 //39 //        } catch (UnsupportedEncodingException e) {40 //            e.printStackTrace();41 //        } catch (IOException e) {42 //            e.printStackTrace();43 //        } catch (JSONException e) {44 //            e.printStackTrace();45 //        }46         47 try {48             49             JSONObject root = new JSONObject();50             root.put("cat", "it");51             52             //{"id":1,"ide":"Eclipse","name":"Java"},53             JSONObject lan1 = new JSONObject();54             lan1.put("id", 1);55             lan1.put("ide", "Eclipse");56             lan1.put("name", "Java");57             58             //{"id":2,"ide":"Xcode","name":"Swift"},59             JSONObject lan2 = new JSONObject();60             lan2.put("id", 2);61             lan2.put("ide", "Xcode");62             lan2.put("name", "Swift");63             64             //{"id":3,"ide":"Visual Studio","name":"C#"}65             JSONObject lan3 = new JSONObject();66             lan3.put("id", 3);67             lan3.put("ide", "Visual Studio");68             lan3.put("name", "C#");69             70             JSONArray array = new JSONArray();71             array.put(lan1);72             array.put(lan2);73             array.put(lan3);74             75             root.put("languages", array);76             77             System.out.println(root.toString());78             79         } catch (JSONException e) {80             // TODO Auto-generated catch block81             e.printStackTrace();82         }83 84     }85 86 }
MainActivity

16_Android的数据存储_ SharedPreference、XML和JSON