1

我有一个应用程序是字典。在 onStart 方法中,FragmentActivity 调用加载器并填充 ListFragment,在其中可以看到具有定义的单词。

在那之前一切正常,但是当我在 SearchView 上放任何字母时,应用程序就会停止。

我知道我的应用程序内的建议路径上的某些内容不起作用。我几乎打赌它是提供程序上的 getSuggestions 光标,与数据库上的 queryForWordsMatchesSuggestions 相连。

我没有使用 SearchManager,因为我不确定是否有必要。无论如何,我的光标必须如何查询数据库以获得建议而不是应用程序崩溃?

我应该在包含加载程序的 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
4

1 回答 1

0

The app was stopping because the SearchManager was not implemented properly.

There is no easy way to manage searches without the SearchManager. At least not for me. And, on the other hand, it is a fully functional already search engine, why use other tool?

于 2014-01-25T03:49:32.113 回答