我检查了许多类似的问题和答案。但在大多数情况下,提问者忘了使用?作为选择中的适配器。这不适合我。 我按照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)
答案 0 :(得分:1)
问题是你的:
if (TextUtils.isEmpty(searchWord)) {
seletionClause = null;
selectionArgs[0] = "";
}
如果selectionClause
为空,则您的selectionArgs
必须为空。另外,您并不需要将两者都保留为成员变量。但是您可以轻松地在本地范围内实例化两者。您还可以更改doQuery
的签名,以接受String selectionClause
和String[] 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个元素的数组(有时是空字符串)。