我有一个字典的应用程序。在onStart方法中,FragmentActivity调用加载器并填充ListFragment,其中可以看到具有定义的单词。
在那之前一切都很好,但是当我在SearchView上放任何字母时,应用就会停止。
我知道我的应用程序内部的建议路径无效。我几乎打赌它是提供者的getSuggestions游标,与数据库上的queryForWordsMatchesSuggestions连接。
我没有使用SearchManager,因为我不确定是否有必要。无论如何,我的光标如何查询数据库以获取建议而不是app colapsing?
我应该在保存加载器的FragmentActivity上构建另一个游标,还是仅仅通过在提供程序中使用正确的游标就足够了?
感谢。
我将把所有建议路由跳转的代码放在有助于接收答案的例子中。
建议路径是这样的:SearchView正在实现OnQueryText更改,正如您在代码段中看到的那样:
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
MenuItem item = menu.add("Search");
item.setIcon(android.R.drawable.ic_menu_search);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM );
SearchView sv = new SearchView(getActivity());
sv.setOnQueryTextListener(this);
item.setActionView(sv);
}
public boolean onQueryTextChange(String newText) {
String newFilter = !TextUtils.isEmpty(newText) ? newText : null;
if (mCurFilter == null && newFilter == null) {
return true;
}
if (mCurFilter != null && mCurFilter.equals(newFilter)) {
return true;
}
mCurFilter = newFilter;
getLoaderManager().restartLoader(0, null, this);
return true;
}
然后,loadermanager注意,调用CONTENT_URI
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Uri baseUri;
if (mCurFilter != null) {
baseUri = Uri.withAppendedPath(DictionaryProvider.CONTENT_URI,
Uri.encode(mCurFilter));
} else {
baseUri = DictionaryProvider.CONTENT_URI; // Why is this not working?
}
String select = "((" + DictionaryDatabase.KEY_WORD + " NOTNULL) AND ("
+ DictionaryDatabase.KEY_WORD + " != '' ))";
return new CursorLoader(getActivity(),
baseUri,
DICTIONARY_PROJECTION,
select,
null, // Select arguments
DictionaryDatabase.KEY_WORD + " COLLATE LOCALIZED ASC");
}
然后,提供者来了。 (我取出了游标getWordsArray和getWord,插入,删除和更新相同)
public class DictionaryProvider extends ContentProvider {
private static final String TAG = "DictionaryProvider";
public static String AUTHORITY = "com.dominicapps.cursorsayouno.DictionaryProvider";
public static final Uri CONTENT_URI = Uri.parse(
"content://" + AUTHORITY + "/dictionary");
public static final String WORDS_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE +
"/vnd.com.dominicapps.cursorsayouno";
public static final String DEFINITION_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE +
"/vnd.com.dominicapps.cursorsayouno";
private DictionaryDatabase mDictionary;
private static final int GET_WORDS_ARRAY = 0;
private static final int GET_WORD = 1;
private static final int SUGGESTIONS = 2; // Is this needed?
private static final UriMatcher sURIMatcher = buildUriMatcher();
private static UriMatcher buildUriMatcher() {
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI(AUTHORITY, "dictionary", GET_WORDS_ARRAY);
matcher.addURI(AUTHORITY, "dictionary/#", GET_WORD);
matcher.addURI(AUTHORITY, "/*", SUGGESTIONS);
return matcher;
}
@Override
public boolean onCreate() {
mDictionary = new DictionaryDatabase(getContext());
return true;
}
@Override
public Cursor query(Uri uri,
String[] projection,
String selection,
String[] selectionArgs,
String sortOrder) {
switch (sURIMatcher.match(uri)) {
case GET_WORDS_ARRAY:
return getWordsArray(selection);
case GET_WORD:
return getWord(uri);
case SUGGESTIONS:
if (selectionArgs == null) {
throw new IllegalArgumentException(
"selectionArgs must be provided for the Uri: " + uri);
}
return getSuggestions(selectionArgs[0]);
default:
throw new IllegalArgumentException("Unknown Uri: " + uri);
}
}
private Cursor getSuggestions(String query) {
String[] columns = new String[] {
BaseColumns._ID,
DictionaryDatabase.KEY_WORD,
DictionaryDatabase.KEY_DEFINITION };
return mDictionary.queryForWordMatchesSuggestions(query, columns);
}
@Override
public String getType(Uri uri) {
switch (sURIMatcher.match(uri)) {
case GET_WORDS_ARRAY:
return WORDS_MIME_TYPE;
case GET_WORD:
return DEFINITION_MIME_TYPE;
default:
throw new IllegalArgumentException("Unknown URL " + uri);
}
}
这是数据库中的查询光标。
public Cursor queryForWordMatchesSuggestions(String query, String[] columns) {
String selection = " rowid = ?";
String[] selectionArgs = new String[] {query+"*"};
return query(selection, selectionArgs, columns);
}
对数据库的一般查询:
public Cursor query(String selection, String[] selectionArgs, String[] columns) {
Log.d(TAG, "+++ query en Proceso +++");
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(FTS_VIRTUAL_TABLE);
builder.setProjectionMap(mColumnMap);
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;
}
而且,这是日志:
06-17 05:31:55.576: W/dalvikvm(597): threadid=12: thread exiting with uncaught exception (group=0x409c01f8)
06-17 05:31:55.587: E/AndroidRuntime(597): FATAL EXCEPTION: AsyncTask #2
06-17 05:31:55.587: E/AndroidRuntime(597): java.lang.RuntimeException: An error occured while executing doInBackground()
06-17 05:31:55.587: E/AndroidRuntime(597): at android.os.AsyncTask$3.done(AsyncTask.java:278)
06-17 05:31:55.587: E/AndroidRuntime(597): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
06-17 05:31:55.587: E/AndroidRuntime(597): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
06-17 05:31:55.587: E/AndroidRuntime(597): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
06-17 05:31:55.587: E/AndroidRuntime(597): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
06-17 05:31:55.587: E/AndroidRuntime(597): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
06-17 05:31:55.587: E/AndroidRuntime(597): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
06-17 05:31:55.587: E/AndroidRuntime(597): at java.lang.Thread.run(Thread.java:856)
06-17 05:31:55.587: E/AndroidRuntime(597): Caused by: java.lang.IllegalArgumentException: Unknown Uri: content://com.dominicapps.cursorsayouno.DictionaryProvider/dictionary/y
06-17 05:31:55.587: E/AndroidRuntime(597): at com.dominicapps.cursorsayouno.DictionaryProvider.query(DictionaryProvider.java:65)
06-17 05:31:55.587: E/AndroidRuntime(597): at android.content.ContentProvider$Transport.query(ContentProvider.java:178)
06-17 05:31:55.587: E/AndroidRuntime(597): at android.content.ContentResolver.query(ContentResolver.java:311)
06-17 05:31:55.587: E/AndroidRuntime(597): at android.content.CursorLoader.loadInBackground(CursorLoader.java:56)
06-17 05:31:55.587: E/AndroidRuntime(597): at android.content.CursorLoader.loadInBackground(CursorLoader.java:42)
06-17 05:31:55.587: E/AndroidRuntime(597): at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:255)
06-17 05:31:55.587: E/AndroidRuntime(597): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:66)
06-17 05:31:55.587: E/AndroidRuntime(597): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:55)
06-17 05:31:55.587: E/AndroidRuntime(597): at android.os.AsyncTask$2.call(AsyncTask.java:264)
06-17 05:31:55.587: E/AndroidRuntime(597): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
06-17 05:31:55.587: E/AndroidRuntime(597): ... 4 more
06-17 05:31:56.227: W/IInputConnectionWrapper(597): showStatusIcon on inactive InputConnection
06-17 05:31:58.086: I/Process(597): Sending signal. PID: 597 SIG: 9
答案 0 :(得分:0)
应用程序正在停止,因为SearchManager未正确实现。
没有SearchManager,没有简单的方法来管理搜索。至少不适合我。而且,另一方面,它是一个功能齐全的搜索引擎,为什么要使用其他工具?