第七章:数据持久化存储
一.对Android来说,主要有三种基本方法存储数据:
Shared preferences 一种轻量级的数据存储机制,用来存储一些简单的数据
传统文件系统
关系型数据库管理系统,通过支持SQLite数据库实现
Android提供SharedPreferences对象帮助用户保存简单的应用数据二.保存和读取用户偏好 使用文件持久保存数据
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jfdimarzio.files"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.jfdimarzio.files.MainActivity"> <TextView android:text="Please enter some text." android:layout_width="245dp" android:layout_height="wrap_content" android:id="@+id/textView" app:layout_constraintLeft_toLeftOf="@+id/activity_main" app:layout_constraintTop_toTopOf="@+id/activity_main" android:layout_marginTop="16dp" app:layout_constraintRight_toRightOf="@+id/activity_main" app:layout_constraintBottom_toTopOf="@+id/editText" android:layout_marginBottom="8dp" app:layout_constraintVertical_bias="0.28" /> <EditText android:layout_width="241dp" android:layout_height="wrap_content" android:inputType="text" android:ems="10" tools:layout_editor_absoluteY="82dp" android:id="@+id/editText" app:layout_constraintLeft_toLeftOf="@+id/activity_main" app:layout_constraintRight_toRightOf="@+id/activity_main" app:layout_constraintTop_toBottomOf="@+id/textView" android:layout_marginTop="136dp"/> <Button android:text="Save" android:layout_width="240dp" android:layout_height="wrap_content" android:id="@+id/btnSave" app:layout_constraintLeft_toLeftOf="@+id/activity_main" android:layout_marginStart="16dp" app:layout_constraintTop_toBottomOf="@+id/editText" android:layout_marginTop="136dp" app:layout_constraintRight_toRightOf="@+id/activity_main" android:layout_marginEnd="16dp" android:onClick="onClickSave" /> <Button android:text="Load" android:layout_width="241dp" android:layout_height="wrap_content" android:id="@+id/btnLoad" app:layout_constraintLeft_toLeftOf="@+id/activity_main" android:layout_marginStart="16dp" app:layout_constraintTop_toBottomOf="@+id/editText" android:layout_marginTop="48dp" app:layout_constraintRight_toRightOf="@+id/activity_main" android:layout_marginEnd="16dp" android:onClick="onClickLoad" /> </android.support.constraint.ConstraintLayout>
package com.jfdimarzio.files; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.Toast; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; public class MainActivity extends AppCompatActivity { EditText textBox; static final int READ_BLOCK_SIZE = 100; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textBox = (EditText) findViewById(R.id.editText); } public void onClickSave(View view) { String str = textBox.getText().toString(); try { FileOutputStream fOut = openFileOutput("textfile.txt", MODE_PRIVATE); OutputStreamWriter osw = new OutputStreamWriter(fOut); //---write the string to the file--- try { osw.write(str); } catch (IOException e) { e.printStackTrace(); } osw.flush(); osw.close(); //---display file saved message--- Toast.makeText(getBaseContext(), "File saved successfully!", Toast.LENGTH_SHORT).show(); //---clears the EditText--- textBox.setText(""); } catch (IOException ioe) { ioe.printStackTrace(); } } public void onClickLoad(View view) { try { FileInputStream fIn = openFileInput("textfile.txt"); InputStreamReader isr = new InputStreamReader(fIn); char[] inputBuffer = new char[READ_BLOCK_SIZE]; String s = ""; int charRead; while ((charRead = isr.read(inputBuffer)) > 0) { //---convert the chars to a String--- String readString = String.copyValueOf(inputBuffer, 0, charRead); s += readString; inputBuffer = new char[READ_BLOCK_SIZE]; } //---set the EditText to the text that has been // read--- textBox.setText(s); Toast.makeText(getBaseContext(), "File loaded successfully!", Toast.LENGTH_SHORT).show(); } catch (IOException ioe) { ioe.printStackTrace(); } } }
三 .创建和使用数据库
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.jfdimarzio.databases.MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="@+id/activity_main" app:layout_constraintLeft_toLeftOf="@+id/activity_main" app:layout_constraintRight_toRightOf="@+id/activity_main" app:layout_constraintTop_toTopOf="@+id/activity_main" /> </android.support.constraint.ConstraintLayout>
package com.jfdimarzio.databases; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class DBAdapter { static final String KEY_ROWID = "_id"; static final String KEY_NAME = "name"; static final String KEY_EMAIL = "email"; static final String TAG = "DBAdapter"; static final String DATABASE_NAME = "MyDB"; static final String DATABASE_TABLE = "contacts"; static final int DATABASE_VERSION = 1; static final String DATABASE_CREATE = "create table contacts (_id integer primary key autoincrement, " + "name text not null, email text not null);"; final Context context; DatabaseHelper DBHelper; SQLiteDatabase db; public DBAdapter(Context ctx) { this.context = ctx; DBHelper = new DatabaseHelper(context); } private static class DatabaseHelper extends SQLiteOpenHelper { DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { try { db.execSQL(DATABASE_CREATE); } catch (SQLException e) { e.printStackTrace(); } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data"); db.execSQL("DROP TABLE IF EXISTS contacts"); onCreate(db); } } //---opens the database--- public DBAdapter open() throws SQLException { db = DBHelper.getWritableDatabase(); return this; } //---closes the database--- public void close() { DBHelper.close(); } //---insert a contact into the database--- public long insertContact(String name, String email) { ContentValues initialValues = new ContentValues(); initialValues.put(KEY_NAME, name); initialValues.put(KEY_EMAIL, email); return db.insert(DATABASE_TABLE, null, initialValues); } //---deletes a particular contact--- public boolean deleteContact(long rowId) { return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0; } //---retrieves all the contacts--- public Cursor getAllContacts() { return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME, KEY_EMAIL}, null, null, null, null, null); } //---retrieves a particular contact--- public Cursor getContact(long rowId) throws SQLException { Cursor mCursor = db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME, KEY_EMAIL}, KEY_ROWID + "=" + rowId, null, null, null, null, null); if (mCursor != null) { mCursor.moveToFirst(); } return mCursor; } //---updates a contact--- public boolean updateContact(long rowId, String name, String email) { ContentValues args = new ContentValues(); args.put(KEY_NAME, name); args.put(KEY_EMAIL, email); return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0; } } package com.jfdimarzio.databases; import android.database.Cursor; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.Toast; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DBAdapter db = new DBAdapter(this); //---add a contact--- db.open(); long id = db.insertContact("Jennifer Ann", "jenniferann@jfdimarzio.com"); id = db.insertContact("Oscar Diggs", "oscar@oscardiggs.com"); db.close(); db.open(); Cursor c = db.getAllContacts(); if (c.moveToFirst()) { do { DisplayContact(c); } while (c.moveToNext()); } db.close(); } public void DisplayContact(Cursor c) { Toast.makeText(this, "id: " + c.getString(0) + "\n" + "Name: " + c.getString(1) + "\n" + "Email: " + c.getString(2), Toast.LENGTH_LONG).show(); } }