使用自定义建议提供程序时,Android中出现奇怪的NullPointerException错误

时间:2013-01-01 20:44:55

标签: java android android-sqlite

我正在尝试在我的应用中制作自定义搜索建议。我从文档和Searchable字典示例开始。但是,这个例子对我来说并不是那么好,所以我开始进行一些测试以确切地知道如何制作它,因为互联网上也没有太多的教程。

通常我的应用程序现在有2个数据库 - 一个正常,第二个列数较少 - FTS3。我想要实现的是将建议提供者连接到此FTS3表。

我试图做的是,现在使用简单的功能,在搜索框中键入任何字母后返回建议整个数据库(大约200条记录)。我知道限制50条记录,但我不认为这是问题所在。 这是来自Provider代码的片段。我发现,当您输入文字时,提供者会转到选项SEARCH_SUGGEST

// UriMatcher stuff
    private static final int SEARCH_WORDS = 0;
    private static final int GET_WORD = 1;
    private static final int SEARCH_SUGGEST = 2;
    private static final int REFRESH_SHORTCUT = 3;
    private static final UriMatcher mUriMatcher = buildUriMatcher();

    /**
     * Builds up a UriMatcher for search suggestion and shortcut refresh queries.
     */
    private static UriMatcher buildUriMatcher() {
        Log.d(TAG,"urimatcher");
        UriMatcher matcher =  new UriMatcher(UriMatcher.NO_MATCH);
        // to get definitions...
        matcher.addURI(AUTHORITY, "mydb", SEARCH_WORDS);
        matcher.addURI(AUTHORITY, "mydb/#", GET_WORD);
        // to get suggestions...
        matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);
        matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST);

        return matcher;
    }

@Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {

switch (mUriMatcher.match(uri)) {
            case SEARCH_SUGGEST:
                Log.d(TAG,"SEARCH_SUGGEST");
                if (selectionArgs == null) {
                  throw new IllegalArgumentException(
                      "selectionArgs must be provided for the Uri: " + uri);
                }
                return getSuggestions(selectionArgs[0]);
            case SEARCH_WORDS:
                Log.d(TAG,"SEARCH_WORDS");
                if (selectionArgs == null) {
                  throw new IllegalArgumentException(
                      "selectionArgs must be provided for the Uri: " + uri);
                }
                return search(selectionArgs[0]);
            case GET_WORD:
                Log.d(TAG,"GET_WORD");
                return null;
            default:
                Log.d(TAG,"default");
                throw new IllegalArgumentException("Unknown Uri: " + uri);
        }
    }

private Cursor getSuggestions(String query) {
        String[] columns = { MyDBAdapter.KEY_TITLE,MyDBAdapter.KEY_ID};
              Log.d(TAG,"query1: " + query);

              try{
                  Cursor tmp = MyDB.getAllEntriesFTS(false, columns,
                        null, null, null, null, MyDBAdapter.KEY_TITLE, null, query);
              Log.d(TAG,"cursor: " + Integer.toString(tmp.getCount()));
              }
              catch(Exception e)
              {
                  Log.d(TAG,e.toString());
              }
              return tmp;
    }

getSuggestions中,我放置了通常应该有效的代码,但事实并非如此。仅在此处使用时不起作用。当我在其他活动中使用它来获取listview的光标时一切都很好。这里它返回我的NullPointerException。

所以越来越深入我在getAllEntriesFTS方法中添加了一些Log标记,这个方法看起来像这样:

public Cursor getAllEntriesFTS(boolean distinct, String[] result_columns,
            String selection, String[] selectionArgs, String groupBy,
            String having, String orderBy, String limit, String query) {

        Log.d(TAG,"query db: " + query);

        String[] columns = { MyDBAdapter.KEY_TITLE, MyDBAdapter.KEY_ID};

        Log.d(TAG,"columns: " + Integer.toString(result_columns.length));

        Cursor allRows = null;
        try{
allRows = db.query(distinct, DATABASE_TABLE_FTS, columns,
                    null, null, null, null, MyDBAdapter.KEY_TITLE, null);
            Log.d(TAG,"OK");
        }
        catch(Exception e)
        {
            Log.d(TAG, e.toString());//it always goes there with NullPointerExceptionwhen used in provider
        }
        Log.d(TAG,Integer.toString(allRows.getCount()));
        return allRows;
    }

所以,generalny说它应该将游标返回到整个数据库,而是抛出它不应该是NullPointerException。

有人可以告诉我,我做错了什么以及应该怎么做?

1 个答案:

答案 0 :(得分:0)

感谢JB Nizet我能找到我的错误。我以为我研究过Google的好榜样,但我错了。

问题是在游标调用之前缺少数据库打开。它应该是这样的:

private Cursor getSuggestions(String query) {
        String[] columns = { MyDBAdapter.KEY_TITLE,MyDBAdapter.KEY_ID};
              Log.d(TAG,"query1: " + query);

              try{
                  MyDB.open();
                  Cursor tmp = MyDB.getAllEntriesFTS(false, columns,
                        null, null, null, null, MyDBAdapter.KEY_TITLE, null, query);
                  MyDB.close();
              Log.d(TAG,"cursor: " + Integer.toString(tmp.getCount()));
              }
              catch(Exception e)
              {
                  Log.d(TAG,e.toString());
              }
              return tmp;
    }

谢谢大家告诉我。