java.lang.IllegalArgumentException:无法绑定索引1处的参数,因为索引超出范围。该语句有0个参数

时间:2015-07-04 11:59:16

标签: android sqlite android-contentprovider illegalargumentexception

我检查了许多类似的问题和答案。但在大多数情况下,提问者忘了使用?作为选择中的适配器。这不适合我。 我按照Content Provider Basics

编写了代码

我的代码如下(对不起我的英文)

public class UserDictActivity extends Activity {
EditText editTextSearch;
ListView wordList;
String searchWord;
Cursor cursor;
SimpleCursorAdapter adapter;
// A projection defines the columns that will be returned for each row
String[] projection = {
        UserDictionary.Words._ID,
        UserDictionary.Words.WORD,
        UserDictionary.Words.LOCALE
};

// Selection defines SELECTE clause "var = ?"
String seletionClause = null;

// Selection arguments define the ? in the SELECT clause
String[] selectionArgs = new String[]{""};

// Defines a list of columns to retrieve from the Cursor and load into an output row
String[] wordListColumns = {
        UserDictionary.Words.WORD,   // Contract class constant containing the word column name
        UserDictionary.Words.LOCALE  // Contract class constant containing the locale column name
};

// Defines a list of View IDs that will receive the Cursor columns for each row
int[] wordListItems = {R.id.tv_word, R.id.tv_local};


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_user_dict);

    editTextSearch = (EditText) findViewById(R.id.et_search);

    wordList = (ListView) findViewById(R.id.lv_wordlist);

    // TODO: Gets a word from the UI
    searchWord = editTextSearch.getText().toString();

    // TODO: Check for invalid or malicious input.

    // If the word is the empty string, gets everything
    if (TextUtils.isEmpty(searchWord)) {
        seletionClause = null;
        selectionArgs[0] = "";
    } else {
        // TODO: Constructs a selection clause that matches the word that the user entered.
        seletionClause = UserDictionary.Words.WORD + " = ?";

        // TODO: Moves the user's input string to the selection arguments.
        selectionArgs[0] = searchWord;
    }

    doQuery();
    // Creates a new SimpleCursorAdapter
    adapter = new SimpleCursorAdapter(
            getApplicationContext(),               // The application's Context object
            R.layout.wordlist_item,                  // A layout in XML for one row in the ListView
            cursor,                               // The result from the query
            wordListColumns,                      // A string array of column names in the cursor
            wordListItems,                        // An integer array of view IDs in the row layout
            0                                    // Flags (usually none are needed)
    );

    wordList.setAdapter(adapter);
}

private void doQuery() {


    // TODO: Does a query against the table and returns a Cursor object
    cursor = getContentResolver().query(
            UserDictionary.Words.CONTENT_URI,
            projection,
            seletionClause,
            selectionArgs,
            null                                // sortOrder
    );

    // Some providers return null if an error occurs, others throw an exception
    if (cursor == null) {
    /*
     * Insert code here to handle the error. Be sure not to use the cursor! You may want to
     * call android.util.Log.e() to log this error.
     *
     */
        Log.e("NullPointerException", "Cursor is NULL");
    }
    // If the Cursor is empty, the provider found no matches
    else if (cursor.getCount() < 1) {

        /*
        * Insert code here to notify the user that the search was unsuccessful. This isn't necessarily
        * an error. You may want to offer the user the option to insert a new row, or re-type the
        * search term.
        */
        Toast.makeText(this, "No word found", Toast.LENGTH_SHORT).show();
    } else {
        // Insert code here to do something with the results

    }
}

}

错误日志如下

07-04 07:06:35.788    1622-1622/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.sinyuk.contentproviderdemo, PID: 1622
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.sinyuk.contentproviderdemo/com.example.sinyuk.contentproviderdemo.UserDictActivity}: java.lang.IllegalArgumentException: Cannot bind argument at index 1 because the index is out of range.  The statement has 0 parameters.
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
        at android.app.ActivityThread.access$800(ActivityThread.java:151)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

2 个答案:

答案 0 :(得分:1)

问题是你的:

  if (TextUtils.isEmpty(searchWord)) {
        seletionClause = null;
        selectionArgs[0] = "";
    }

如果selectionClause为空,则您的selectionArgs必须为空。另外,您并不需要将两者都保留为成员变量。但是您可以轻松地在本地范围内实例化两者。您还可以更改doQuery的签名,以接受String selectionClauseString[] selectionArgs,从而将自己保留为成员类的必要性释放自己。 E.g。

if (TextUtils.isEmpty(searchWord)) {
    seletionClause = null;
    selectionArgs = null;
} else {
    // TODO: Constructs a selection clause that matches the word that the user entered.
    seletionClause = UserDictionary.Words.WORD + " = ?";

    // TODO: Moves the user's input string to the selection arguments.
    selectionArgs = new String[] { searchWord };
}

doQuery(selectionClause, selectionArgs);



private void doQuery(String selectionClause, String[] selectionArgs) {
  //
}

答案 1 :(得分:0)

selectionArgs的大小应为零,或者当selectionClause为null时为null。 在您当前的代码中,它是一个总是包含1个元素的数组(有时是空字符串)。