Android笔记----Android的数据存储和IO操作

使用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>
时间: 2024-10-09 08:16:02

Android笔记----Android的数据存储和IO操作的相关文章

Android笔记——Android中数据的存储方式(二)

我们在实际开发中,有的时候需要储存或者备份比较复杂的数据.这些数据的特点是,内容多.结构大,比如短信备份等.我们知道SharedPreferences和Files(文本文件)储存这种数据会非常的没有效率.如果学过JavaWeb的朋友,首先可能想到的是数据库.当然了数据库是一个方案,那么是否还有其他的解决方案呢?今天我们在讲下Android笔记——Android中数据的存储方式(一) 提到的除了SharedPreferences和Files(文本文件)以外的其他几种数据储存方式:xml文件.SQL

Android开发系列之数据存储(一)

  Android开发中,数据存储主要有五种:网络.数据库.SharePreferences.文件以及Content Provider.   . 数据库    Android中的数据库最常用的是Sqlite. 使用Sqlite进行数据存储,可分为以下几步:    . 继承SqliteOpenHelper    . 整理4个构造方法    . 重写onCreate与onUpgrade      public class DownDBHelper extends SQLiteOpenHelper {

Android的4中数据存储方式

Android的4中数据存储方式:1.SharedPreference2.SQLite3.ContentProvider4.File 1.SharedPreference 1)轻量级数据存储方式A 2)本质是基于XML文件存储key-value键值对数据 3)用于保存应用程序的 参数/属性的配置信息 SharedPreference对象本身只能获取数据而不支持存储和修改,修改是通过Editor来实现 实现SharedPreference存储的步骤: (1)获得SharedPreference对象

转载:android笔记--android中的多线程--Handler, Looper, MessageQueue, Message类

什么时候使用多线程: 1. 耗时操作使用多线程, 耗时操作放在UI线程中会导致用户的操作无法得到响应. 2. 阻塞操作使用多线程, 理由同上. 3. 多核CUP的设备使用多线程, 可以有效提高CPU的利用率. 4. 并行操作使用多线程. android中的多线程模型主要涉及的类有:Looper, Handler, MessageQueue, Message等. 一:Looper类: 1 static final ThreadLocal<Looper> sThreadLocal = new Th

iOS 学习笔记——0005(数据存储)

先发一个练手的小demo,自己写的简略通讯录,已上传至github https://github.com/liaoshaolim/addressBook 1.NSKeyedArchiver:(归档) 这里用一个添加联系人的例子来说明: 注意:归档形式保存数据,需要该对象遵守NSCoding协议,而且对应的必须提供encodeWithCoder和initWithCoder方法 因为归档是一次性的,解压也是一次性的,所以小量的ok,如果量大的话,改一个小地方就要归档或解压全部,效率会比较低 //用一

android关于SD卡、存储的各种操作

getExternalFilesDir getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath()返回的是图片存放的标准目录,应用被卸载时这个目录也会被删除.参数还有:public static String DIRECTORY_ALARMS系统提醒铃声存放的标准目录.public static String DIRECTORY_DCIM 相机拍摄照片和视频的标准目录.public static String DIR

CR开发笔记-6用户数据存储

仍然是贴代码 using UnityEngine; using System.Collections; public class DateControl : MonoBehaviour { public static string Name; public static int Num; bool JBstart; float fullWidth; float fullHeight; Rect fullScreen; //窗口 Rect NameText; Rect GoBtn; Rect po

【Android】数据存储-java IO流文件存储

1.数据持久化:将在内存中的瞬时数据保存在存储设备中.瞬时数据:设备关机数据丢失.持久化技术提供一种机制可以让数据在瞬时状态和持久状态之间转换. 2.Android中简单的三种存储方式:文件存储.SharedPreference 存储以及数据库存储. 1.文件存储 :不对数据作任何处理,将数据原封不动地存储到文件中,适合存储一些简单的文本数据和二进制数据. a.将数据存储到文件中 Context类提供了一个openFileOutput()方法,可以用于将数据存储到文件中.这个方法接收两个参数,第

Android笔记——Android中数据的存储方式(三)

Android系统集成了一个轻量级的数据库:SQLite,所以Android对数据库的支持很好,每个应用都可以方便的使用它.SQLite作为一个嵌入式的数据库引擎,专门适用于资源有限的设备上适量数据存取,现在的主流移动设备像Android.iPhone等都使用SQLite作为复杂数据的存储引擎,并且它是以手机内存为储存的. 那么,实际开发项目中有大量数据需要读写,并且需要面临大量用户的并发储存的情况呢.就不应该把数据存放在手机等移动设备的SQLite数据库里,移动设备的储存能力和计算能力都不足以