W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
編寫:Lin-H - 原文:http://developer.android.com/training/search/search.html
有很多方法可以儲(chǔ)存你的數(shù)據(jù),比如儲(chǔ)存在線上的數(shù)據(jù)庫,本地的SQLite數(shù)據(jù)庫,甚至是文本文件。你自己來選擇最適合你應(yīng)用的存儲(chǔ)方式。本節(jié)課程會(huì)向你展示如何創(chuàng)建一個(gè)健壯的可以提供全文搜索的SQLite虛擬表。并從一個(gè)每行有一組單詞-解釋對(duì)的文件中將數(shù)據(jù)填入。
虛擬表與SQLite表的運(yùn)行方式類似,但虛擬表是通過回調(diào)來向內(nèi)存中的對(duì)象進(jìn)行讀取和寫入,而不是通過數(shù)據(jù)庫文件。要?jiǎng)?chuàng)建一個(gè)虛擬表,首先為該表創(chuàng)建一個(gè)類:
public class DatabaseTable {
private final DatabaseOpenHelper mDatabaseOpenHelper;
public DatabaseTable(Context context) {
mDatabaseOpenHelper = new DatabaseOpenHelper(context);
}
}
在DatabaseTable
類中創(chuàng)建一個(gè)繼承SQLiteOpenHelper的內(nèi)部類。你必須重寫類SQLiteOpenHelper中定義的abstract方法,才能在必要的時(shí)候創(chuàng)建和更新你的數(shù)據(jù)庫表。例如,下面一段代碼聲明了一個(gè)數(shù)據(jù)庫表,用來儲(chǔ)存字典app所需的單詞。
public class DatabaseTable {
private static final String TAG = "DictionaryDatabase";
//字典的表中將要包含的列項(xiàng)
public static final String COL_WORD = "WORD";
public static final String COL_DEFINITION = "DEFINITION";
private static final String DATABASE_NAME = "DICTIONARY";
private static final String FTS_VIRTUAL_TABLE = "FTS";
private static final int DATABASE_VERSION = 1;
private final DatabaseOpenHelper mDatabaseOpenHelper;
public DatabaseTable(Context context) {
mDatabaseOpenHelper = new DatabaseOpenHelper(context);
}
private static class DatabaseOpenHelper extends SQLiteOpenHelper {
private final Context mHelperContext;
private SQLiteDatabase mDatabase;
private static final String FTS_TABLE_CREATE =
"CREATE VIRTUAL TABLE " + FTS_VIRTUAL_TABLE +
" USING fts3 (" +
COL_WORD + ", " +
COL_DEFINITION + ")";
DatabaseOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mHelperContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
mDatabase = db;
mDatabase.execSQL(FTS_TABLE_CREATE);
}
@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 " + FTS_VIRTUAL_TABLE);
onCreate(db);
}
}
}
現(xiàn)在,表需要數(shù)據(jù)來儲(chǔ)存。下面的代碼會(huì)向你展示如何讀取一個(gè)內(nèi)容為單詞和解釋的文本文件(位于res/raw/definitions.txt
),如何解析文件與如何將文件中的數(shù)據(jù)按行插入虛擬表中。為防止UI鎖死這些操作會(huì)在另一條線程中執(zhí)行。將下面的一段代碼添加到你的DatabaseOpenHelper
內(nèi)部類中。
Tip:你也可以設(shè)置一個(gè)回調(diào)來通知你的UI activity線程的完成結(jié)果。
private void loadDictionary() {
new Thread(new Runnable() {
public void run() {
try {
loadWords();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
}
private void loadWords() throws IOException {
final Resources resources = mHelperContext.getResources();
InputStream inputStream = resources.openRawResource(R.raw.definitions);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
String line;
while ((line = reader.readLine()) != null) {
String[] strings = TextUtils.split(line, "-");
if (strings.length < 2) continue;
long id = addWord(strings[0].trim(), strings[1].trim());
if (id < 0) {
Log.e(TAG, "unable to add word: " + strings[0].trim());
}
}
} finally {
reader.close();
}
}
public long addWord(String word, String definition) {
ContentValues initialValues = new ContentValues();
initialValues.put(COL_WORD, word);
initialValues.put(COL_DEFINITION, definition);
return mDatabase.insert(FTS_VIRTUAL_TABLE, null, initialValues);
}
任何恰當(dāng)?shù)牡胤?,都可以調(diào)用loadDictionary()
方法向表中填入數(shù)據(jù)。一個(gè)比較好的地方是DatabaseOpenHelper
類的onCreate())方法中,緊隨創(chuàng)建表之后:
@Override
public void onCreate(SQLiteDatabase db) {
mDatabase = db;
mDatabase.execSQL(FTS_TABLE_CREATE);
loadDictionary();
}
當(dāng)你的虛擬表創(chuàng)建好并填入數(shù)據(jù)后,根據(jù)SearchView提供的請(qǐng)求搜索數(shù)據(jù)。將下面的方法添加到DatabaseTable
類中,用來創(chuàng)建搜索請(qǐng)求的SQL語句:
public Cursor getWordMatches(String query, String[] columns) {
String selection = COL_WORD + " MATCH ?";
String[] selectionArgs = new String[] {query+"*"};
return query(selection, selectionArgs, columns);
}
private Cursor query(String selection, String[] selectionArgs, String[] columns) {
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(FTS_VIRTUAL_TABLE);
Cursor cursor = builder.query(mDatabaseOpenHelper.getReadableDatabase(),
columns, selection, selectionArgs, null, null, null);
if (cursor == null) {
return null;
} else if (!cursor.moveToFirst()) {
cursor.close();
return null;
}
return cursor;
}
調(diào)用getWordMatches()
來搜索請(qǐng)求。任何符合的結(jié)果返回到Cursor中,可以直接遍歷或是建立一個(gè)ListView。這個(gè)例子是在檢索activity的handleIntent()
方法中調(diào)用getWordMatches()
。請(qǐng)記住,因?yàn)橹皠?chuàng)建的intent filter,檢索activity會(huì)在ACTION_SEARCH intent中額外接收請(qǐng)求作為變量存儲(chǔ):
DatabaseTable db = new DatabaseTable(this);
...
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
Cursor c = db.getWordMatches(query, null);
//執(zhí)行Cursor并顯示結(jié)果
}
}
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: