使用SharedPreferences
File存储
SQLite数据库
使用SharedPreferences
1.1 SharedPreferences与Editor简介
应用程序有少量的数据需要保存,而且这些数据的格式很简单,都是普通的字符串、标量类型的值等,比如应用程序的各种配置信息,对于这种数据,Android提供了SharedPreferences。
SharedPreferences保存的数据主要是类似于配置信息格式的数据,因此它保存的数据主要是简单类型的key-value对。 SharedPreferences接口主要负责读取应用程序的Preferences数据,它提供了如下常方法来访问SharedPreferences中的key-value对。
boolean contains(String key):判断SharedPreferences是否包含特定key的数据。
abstract Map<String, ?>getAll():获取SharedPreferences数据里全部的key-value对。
boolean getXxx(String key,xxx defValue):获取SharedPreferences数据里指定的key对应的value。如果key值不存在,返回默认值defValue。其中xxx可以是boolean、float、int、long、String等各种基本类型的值。
SharedPreferences接口本身并没有提供写入数据的能力,而是通过SharedPreferences的内部接口, SharedPreferences调用edit()方法即可获取它所对应的Editor对象,提供了如下方法向SharedPreferences写入数据。
SharedPreferences.Editor clear():清空SharedPreferences里所有数据。
SharedPreferences.Editor putXxx(String key, xxx value):向SharedPreferences存入指定key对应的数据。其中xxx可以是boolean、float、int、long、String等各种基本类型的值。
SharedPreferences.Editor remove(String key):删除SharedPreferences里指定的key对应的数据项。
boolean commit() :当Editor编辑完成后,调用该方法提交修改。
SharedPreferences是一个接口,程序无法直接创建其实例,只能通过Context提供的getSharedPreferences(String name,int mode) 方法来获取SharedPreferences实例。该方法的第二个参数支持如下几个值。
Context.MODE_PRIVATE:指定SharedPreferences数据只能被本应用程序读、写。
Context.MODE_WORLD_READABLE:指定SharedPreferences数据能被其他应用程读,但不能写。
Context.MODE_WORLD_WRITEABLE:指定SharedPreferences数据能被其他应用程读、写。
例:SharedPreferences的存储位置和格式:
SharedPreferencesDemo.java
public class SharedPreferencesDemo extends Activity { SharedPreferences preferences; SharedPreferences.Editor editor; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取只能被本应用程序读、写的SharedPreferences对象 preferences = getSharedPreferences("hello", MODE_WORLD_READABLE); editor = preferences.edit(); Button read = (Button) findViewById(R.id.read); Button write = (Button) findViewById(R.id.write); read.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { //读取字符串数据 String time = preferences.getString("time", null); //读取int类型的数据 int randNum = preferences.getInt("random", 0); String result = time == null ? "您暂时还未写入数据" : "写入时间为:" + time + "\n上次生成的随机数为:" + randNum; //使用Toast提示信息 Toast.makeText(SharedPreferencesTest.this , result , 5000) .show(); } }); write.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 " + "hh:mm:ss"); // 存入当前时间 editor.putString("time", sdf.format(new Date())); // 存入一个随机数 editor.putInt("random", (int) (Math.random() * 100)); // 提交所有存入的数据 editor.commit(); } }); } }
运行程序后,点击“写入数据”,程序将完成SharedPreferences写入写入完成后,打开DDMS的File Explorer面板,SharedPreferences数据保存在/data/datta/com.whq/shared_prefs目录下, SharedPreferences数据是以XML格式保存。
1.2 要读、写其他应用的SharedPreferences
要读、写其他应用的SharedPreferences,前提是创建该SharedPreferences的应用程序指定相应的访问权限,例如指定了MODE_WORLD_READABLE,这表明该SharedPreferences可被其他应用程序读取;指定MODE_WORLD_WRITEABLE,这表明该SharedPreferences可被其他程序写入。
为了读取其他程序的SharedPreferences,可按如下步骤进行。
需要创建其他程序对应的Context。
调用其他应用程序的Context的getSharedPreferences(String name,int mode) 即可获取相应的SharedPreferences对象。
如果需要向其他应用的SharedPreferences数据写入数据,调用SharedPreferences的edit()方法获取相应的Editor即可。
例:读取其他应用程序的SharedPreferences数据:
UseCount .java
package com.Xxx; public class UseCount extends Activity { SharedPreferences preferences; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); preferences = getSharedPreferences("count", MODE_WORLD_READABLE); //读取SharedPreferences里的count数据 int count = preferences.getInt("count" , 0); //显示程序以前使用的次数 Toast.makeText(this , "程序以前被使用了" + count + "次。", 10000) .show(); Editor editor = preferences.edit(); //存入数据 editor.putInt("count" , ++count); //提交修改 editor.commit(); } }
ReadOtherPreferences.java
public class ReadOtherPreferences extends Activity { Context useCount; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //Context useCount = null; try { // 获取其他程序所对应的Context(com.Xxx:UseCount所在包名) useCount = createPackageContext("com.Xxx", Context.CONTEXT_IGNORE_SECURITY); } catch (NameNotFoundException e) { e.printStackTrace(); } // 使用其他程序的Context获取对应的SharedPreferences SharedPreferences prefs = useCount.getSharedPreferences("count", Context.MODE_WORLD_READABLE); // 读取数据 int count = prefs.getInt("count", 0); TextView show = (TextView) findViewById(R.id.show); // 显示读取的数据内容 show.setText("UseCount应用程序以前被使用了" + count + "次。"); } }
File存储
2.1 openFileOutput和openFileInput
Context提供了如下两个方法来打开本应用程序的数据文件夹里的文件IO流。
FileInputStream openFileInput(String name):打开应用程序的数据文件夹下的name文件对应的输入流。
FileOutputStream openFileOutput(String name,int mode):打开应用程序的数据文件夹下的name文件对应输出流。
上面两个方法分别用于打开文件输入流、输出流。其中第二个方法的第二个参数指定打开文件夹的模式,该模式支持如下值。
MODE_PRIVATE:该文件只能被当前程序读写。
MODE_APPEND:以追加方式打开该文件,应用程序可以向该文件追加内容。
MODE_WORLD_READABLE:该文件的内容可以被其他程序读取。
MODE_WORLD_WRITEABLE:该文件的内容可由其他程序读写。
Context还提供了如下几个方法来访问应用程序的数据文件夹。
getDir(String name,int mode):在应用程序的数据文件夹下获取或创建name对应的子目录。
File getFilesDir():获取该应用程序的数据文件夹的绝对路径。
String[] fileList():返回该应用程序的数据文件夹下的全部文件。
deleteFile(String):删除该应用程序的数据文件夹下的指定内容。
例:读写应用程序数据文件夹下内容:
Main.xml
<?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" > <EditText android:id="@+id/edit1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:lines="4" /> <Button android:id="@+id/write" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/write" /> <EditText android:id="@+id/edit2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:cursorVisible="false" android:editable="false" android:lines="4" /> <Button android:id="@+id/read" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/read" /> </LinearLayout>
FileTest.java
public class FileTest extends Activity { final String FILE_NAME = "test.txt"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); System.out.println(new StringBuilder("a").append("b").append("c") .toString()); // 获取两个按钮 Button read = (Button) findViewById(R.id.read); Button write = (Button) findViewById(R.id.write); // 获取两个文本框 final EditText edit1 = (EditText) findViewById(R.id.edit1); final EditText edit2 = (EditText) findViewById(R.id.edit2); // 为write按钮绑定事件监听器 write.setOnClickListener(new OnClickListener() { @Override public void onClick(View source) { // 将edit1中的内容写入文件中 write(edit1.getText().toString()); edit1.setText(""); } }); read.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 读取指定文件中的内容,并显示出来 edit2.setText(read()); } }); } private String read() { try { // 打开文件输入流 FileInputStream fis = openFileInput(FILE_NAME); byte[] buff = new byte[1024]; int hasRead = 0; StringBuilder sb = new StringBuilder(""); while ((hasRead = fis.read(buff)) > 0) { sb.append(new String(buff, 0, hasRead)); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); } return null; } private void write(String content) { try { // 以追加模式打开文件输出流 FileOutputStream fos = openFileOutput(FILE_NAME, MODE_APPEND); // 将FileOutputStream包装成PrintStream PrintStream ps = new PrintStream(fos); // 输出文件内容 ps.println(content); ps.close(); } catch (Exception e) { e.printStackTrace(); } } }
注:test.txt所在位置:打开File Explorer:data/data/com.Xxx包名/file/test.txt
2.2 读写SD卡上的文件
当程序通过Context的openFileInput或openFileOutput来打开文件输入流、输出流时,程序所打开的都是应用程序的数据文件夹里的文件,这样所存储的文件大小可能比较有限。为了更好的存、取应用程序的大文件数据,应用程序需要读、写SD卡上的文件。步骤如下:
调用Environment的getExternalStorageState()方法判断手机上是否插入了SD卡,并且应用程序具有读写SD卡的权限。
调用Environment的getExternalStorageDirectory()方法来获取SD卡的目录。
使用FileInputStream、FileOutputStream、FileReader或FileWriter读写SD卡里的文件。
例:读写SD卡的内容:
SDCardTest.java
public class SDCardTest extends Activity { final String FILE_NAME = "/test.txt"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取两个按钮 Button read = (Button) findViewById(R.id.read); Button write = (Button) findViewById(R.id.write); // 获取两个文本框 final EditText edit1 = (EditText) findViewById(R.id.edit1); final EditText edit2 = (EditText) findViewById(R.id.edit2); // 为write按钮绑定事件监听器 write.setOnClickListener(new OnClickListener() { @Override public void onClick(View source) { // 将edit1中的内容写入文件中 write(edit1.getText().toString()); edit1.setText(""); } }); read.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 读取指定文件中的内容,并显示出来 edit2.setText(read()); } }); } private String read() { try { //如果手机插入了SD卡,而且应用程序具有访问SD的权限 if (Environment.getExternalStorageState() .equals(Environment.MEDIA_MOUNTED)) { //获取SD卡对应的存储目录 File sdCardDir = Environment.getExternalStorageDirectory(); //获取指定文件对应的输入流 FileInputStream fis = new FileInputStream(sdCardDir .getCanonicalPath() + FILE_NAME); //将指定输入流包装成BufferedReader BufferedReader br = new BufferedReader(new InputStreamReader(fis)); StringBuilder sb = new StringBuilder(""); String line = null; while((line = br.readLine()) != null) { sb.append(line); } return sb.toString(); } } catch (Exception e) { e.printStackTrace(); } return null; } private void write(String content) { try { //如果手机插入了SD卡,而且应用程序具有访问SD的权限 if (Environment.getExternalStorageState() .equals(Environment.MEDIA_MOUNTED)) { //获取SD卡的目录 File sdCardDir = Environment.getExternalStorageDirectory(); File targetFile = new File(sdCardDir.getCanonicalPath() + FILE_NAME); //以指定文件创建 RandomAccessFile对象 RandomAccessFile raf = new RandomAccessFile( targetFile , "rw"); //将文件记录指针移动到最后 raf.seek(targetFile.length()); // 输出文件内容 raf.write(content.getBytes()); raf.close(); } } catch (Exception e) { e.printStackTrace(); } } }
应用程序读、写SD卡文件请注意:
Android模拟器可通过mksdcard命令来创建虚拟存储卡
为了读写SD卡上的数据,必须在应用程序的AndroidManifest.xml中添加读写SD卡的权限。配置内容如下:
<!--SD卡创建与删除文件权限-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- SD卡写入数据权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
SQLite数据库
Android系统集成了一个轻量级的数据库:SQLite,SQLite只是一个嵌入式的数据库引擎,专门适用于资源有限的设备上(如手机、PDA等)适量数据存取。 SQLite数据库只是一个文件,不需要安装、启动服务器进程。
3.1 简介SQLiteDatabase
Android提供了SQLiteDatabase代表一个数据库(底层就是一个数据库文件),一旦应用程序获得了代表指定数据库的SQLiteDatabase对象,接下来就可以管理、操作数据库了。
SQLiteDatabase提供了如下静态方法来打开一个文件对应的数据库
SQLiteDatabase openDatabase(String path, SQLiteDatabase. CursorFactory factroy, int flags):打开path文件所代表SQLite数据库。
SQLiteDatabase openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory):打开或创建(如果 不存在)path文件所代表SQLite数据库。
在程序中获取SQLiteDatabase对象后,接下来就可调用其如下方法来操作数据库。
execSQL(String sql,Object[] bindArgs):执行带占位符的SQL语句。
execSQL(String sql):执行SQL语句。
insert(String table,String nullColumnHack,ContentValues values):向执行表中插入数据。
update(String table,ContentValues values,String whereClause,String[] whereArgs):更新指定数据库。
delete(String table,String whereClause,String[] whereArgs):删除指定表中的特定数据。
Cursor query(String table,String[] columns,String selection, String[] selectionArgs,String groupBy,String having,String orderBy):对执行数据表执行查询。
Cursor query(String table,String[] columns,String selection, String[] selectionArgs,String groupBy,String having,String orderBy,String limit):对执行数据表执行查询,limit对数控制最多查询几条记录。
rawQuery(String sql,String[] selectionArgs):执行带占位符的SQL查询。
begin Transaction():开始事务。
end Transaction():结束事务。
上面查询方法都是返回一个Cursor对象,Android中的Cursor类似于JDBC的ResultSet,Cursor提供如下方法来移动查询结果的记录指针。
move(int offset):将记录指针向上或向下移动指定的行数.
boolean moveToFirst():将记录指针移到到第一行。
boolean moveToLast():将记录指针移到到最后一行。
boolean moveToNext():将记录指针移到到下一行。
boolean moveToPosition(int position):将记录指针移到到指定行。
boolean moveToPrevious():将记录指针移到到上一行。
一旦记录指针移到到指定行后,接下来就可以调用Cursor的getXxx()方法来获取该行的指定列的数据。
3.2 创建数据库和表
使用SQLiteDatabase的静态方法即可打开或创建数据库,例如如下代码:
SQLiteDatabase.openOrCreateDatabase(“/mt/db/temp.db3”,null);
上面的代码即可返回一个SQLiteDatabase对象,该对象的execSQL可执行任意的SQL语句,因此程序可通过如下代码在程序中创建数据表:
//定义建表语句
sql=“create table user_inf(user_id integer primary key,”+” user_name varchar(255),”+”user_pass varchar(255))”
//执行SQL语句
db.execSQL(sql);
在程序中执行上面的代码即可在数据库中创建一个数据表。
3.3使用SQL语句操作SQLite数据库
使用SQLiteDatabase进行数据库操作的步骤如下:
获取SQLiteDatabase对象,进行与数据库连接。
调用SQLiteDatabase的方法来执行SQL语句。
操作SQL语句的执行结果,比如用SimpleCursorAdapter封装成Cursor。
调用close()方法,关闭SQLiteDatabase数据库,回收资源。
例:
DBTest.java
public class DBTest extends Activity { SQLiteDatabase db; Button bn = null; ListView listView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //创建或打开数据库(此处需要使用绝对路径) db = SQLiteDatabase.openOrCreateDatabase(this.getFilesDir() .toString() + "/test.db3" , null); listView = (ListView)findViewById(R.id.show); bn = (Button)findViewById(R.id.ok); bn.setOnClickListener(new OnClickListener() { @Override public void onClick(View source) { //获取用户输入 String title = ((EditText)findViewById(R.id.title)) .getText().toString(); String content = ((EditText)findViewById(R.id.content)) .getText().toString(); try { insertData(db , title , content); Cursor cursor = db.rawQuery("select * from news_inf", null); inflateList(cursor); } catch(SQLiteException se) { //执行DDL创建数据表 db.execSQL("create table news_inf(_id integer primary key autoincrement," + " news_title varchar(50)," + " news_content varchar(255))"); //执行insert语句插入数据 insertData(db , title , content); //执行查询 Cursor cursor = db.rawQuery("select * from news_inf", null); inflateList(cursor); } } }); } private void insertData(SQLiteDatabase db , String title , String content) { //执行插入语句 db.execSQL("insert into news_inf values(null , ? , ?)" , new String[]{title , content}); } private void inflateList(Cursor cursor) { //填充SimpleCursorAdapter SimpleCursorAdapter adapter = new SimpleCursorAdapter( DBTest.this , R.layout.line, cursor , new String[]{"news_title" , "news_content"} , new int[]{R.id.my_title , R.id.my_content}); //显示数据 listView.setAdapter(adapter); } @Override public void onDestroy() { super.onDestroy(); //退出程序时关闭SQLiteDatabase if (db != null && db.isOpen()) { db.close(); } } }
Main.xml
<?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" > <EditText android:id="@+id/title" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <EditText android:id="@+id/content" android:layout_width="fill_parent" android:layout_height="wrap_content" android:lines="2" /> <Button android:id="@+id/ok" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/insert" /> <ListView android:id="@+id/show" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
3.4使用sqlite3工具
在Android SDK的tools目录下提供了一个sqlite.exe,它是一个简单的SQLite数据库管理工具,利用该工具可以来查询、管理数据库。
SQLilte内部只支持NULL、INTEGER、REAL、TEXT和BLOB这5种数据类型。
它允许把各种类型的数据保存到任务类型的字段中,不必关心声明该字段所使用的数据类型。
SQLilte允许存入数据时忽略底层数据列实际的数据类型。
3.5 使用特定方法操作数据库
1.使用insert方法插入记录。
SQLiteDatabase的insert方法long insert(String table,String nullCoumnHack,ContentValues values)
table:代表要插入数据的表名
nullCoumnHack:代表强行插入null值的数据列的列名。
values:代表一行记录的数据。
insert方法插入的一条记录使用ContentValues存放,ContentValues类似于Map,提供了put(String key,Xxx value)方法存入数据。getAsXxx(String key)方法取出数据。
2.使用update方法更新记录
SQLiteDatabase的update方法为update(String table,ContentValues values,String whereClause,String[] whereArgs),该方法返回受此update语句影响的记录的条数。
table:代表要更新数据的表名
values:代表想更新的数据。
whereClause:满足该whereClause子句的记录将会被更新。
whereArgs:用于为whereClause子句传入参数。
3.使用delete方法删除记录
SQLiteDatabase的delete方法为delete(String table,String whereClause,String[] whereArgs),该方法返回受此delete语句影响的记录的条数。
table:代表要删除数据的表名
whereClause:满足该whereClause子句的记录将会被删除。
whereArgs:用于为whereClause子句传入参数。
4.使用query方法查询记录
SQLiteDatabase的query方法的签名为Cusor query(boolean distinct,String table,String[] columns,String selection, String[] selectionArgs,String groupBy,String having,String orderBy,String limit):参数说明如下。
distinct:指定是否去除重复记录。
table:代表查询数据的表名。
columns:要查询出来的列名。
selection:查询条件子句。
selectionArgs:占位符传入参数值。
groupBy:用于控制分组。
having:用于对分组进行过滤。
orderBy:用于对记录进行排序。
limit:用于进行分页。
3.6 SQLiteOpenHelper
SQLiteOpenHelper是一个辅助类,可用于管理数据库的创建和版本更新。SQLiteOpenHelper是个抽象类,一般的用法是创建SQLiteOpenHelper的子类,并重写它的onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion)方法。
SQLiteOpenHelper包含如下常用方法:
getReadableDatabase():以读写的方法打开数据库对应SQLiteDatabase对象。
getWritableDatabase():以写的方法打开数据库对应SQLiteDatabase对象。
onCreate():当第一次创建数据库时回调该方法。
onUpgrade():当数据库版本更新时回调该方法。
close():关闭所打开的SQLiteDatabase对象
例子:简单生词本
MyDatabaseHelper.java
public class MyDatabaseHelper extends SQLiteOpenHelper { final String CREATE_TABLE_SQL = "create table dict(_id integer primary key autoincrement , word , detail)"; public MyDatabaseHelper(Context context, String name, int version) { super(context, name, null, version); } @Override public void onCreate(SQLiteDatabase db) { // 第一个使用数据库时自动建表 db.execSQL(CREATE_TABLE_SQL); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { System.out.println("--------onUpdate Called--------" + oldVersion + "--->" + newVersion); } }
Dict.java
public class Dict extends Activity { MyDatabaseHelper dbHelper; Button insert = null; Button search = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 创建MyDatabaseHelper对象,指定数据库版本为1,此处使用相对路径即可, // 数据库文件自动会保存在程序的数据文件夹的databases目录下。 dbHelper = new MyDatabaseHelper(this , "myDict.db3" , 1); insert = (Button)findViewById(R.id.insert); search = (Button)findViewById(R.id.search); insert.setOnClickListener(new OnClickListener() { @Override public void onClick(View source) { //获取用户输入 String word = ((EditText)findViewById(R.id.word)) .getText().toString(); String detail = ((EditText)findViewById(R.id.detail)) .getText().toString(); //插入生词记录 insertData(dbHelper.getReadableDatabase() , word , detail); //显示提示信息 Toast.makeText(Dict.this, "添加生词成功!" , 8000) .show(); } }); search.setOnClickListener(new OnClickListener() { @Override public void onClick(View source) { // 获取用户输入 String key = ((EditText) findViewById(R.id.key)).getText() .toString(); // 执行查询 Cursor cursor = dbHelper.getReadableDatabase().rawQuery( "select * from dict where word like ? or detail like ?", new String[]{"%" + key + "%" , "%" + key + "%"}); //创建一个Bundle对象 Bundle data = new Bundle(); data.putSerializable("data", converCursorToList(cursor)); //创建一个Intent Intent intent = new Intent(Dict.this , ResultActivity.class); intent.putExtras(data); //启动Activity startActivity(intent); } }); } protected ArrayList<Map<String , String>> converCursorToList(Cursor cursor) { ArrayList<Map<String , String>> result = new ArrayList<Map<String , String>>(); //遍历Cursor结果集 while(cursor.moveToNext()) { //将结果集中的数据存入ArrayList中 Map<String , String> map = new HashMap<String , String>(); //取出查询记录中第2列、第3列的值 map.put("word" , cursor.getString(1)); map.put("detail" , cursor.getString(2)); result.add(map); } return result; } private void insertData(SQLiteDatabase db , String word , String detail) { //执行插入语句 db.execSQL("insert into dict values(null , ? , ?)" , new String[]{word , detail}); } @Override public void onDestroy() { super.onDestroy(); //退出程序时关闭MyDatabaseHelper里的SQLiteDatabase if (dbHelper != null) { dbHelper.close(); }}}
ResultActivity.java
public class ResultActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.popup); ListView listView = (ListView)findViewById(R.id.show); Intent intent = getIntent(); //获取该intent所携带的数据 Bundle data = intent.getExtras(); //从Bundle数据包中取出数据 @SuppressWarnings("unchecked") List<Map<String , String>> list = (List<Map<String , String>>)data.getSerializable("data"); //将List封装成SimpleAdapter SimpleAdapter adapter = new SimpleAdapter( ResultActivity.this , list , R.layout.line , new String[]{"word" , "detail"} , new int[]{R.id.word , R.id.detail}); //填充ListView listView.setAdapter(adapter); } }
Main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <EditText android:id="@+id/word" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/input" /> <EditText android:id="@+id/detail" android:layout_width="fill_parent" android:layout_height="wrap_content" android:lines="3" android:hint="@string/input" /> <Button android:id="@+id/insert" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/insert" /> <EditText android:id="@+id/key" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="@string/record" /> <Button android:id="@+id/search" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/search" /> <ListView android:id="@+id/show" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
string.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">生词本</string> <string name="insert">添加生词</string> <string name="search">查找</string> <string name="detail">解释</string> <string name="input">请输入...</string> <string name="record">暂无</string> </resources>