I have taken the following code snippet from the 5th snippet on this developer guide on Content Providers.
The confusion is that in the first statement String[] mSelectionArgs = {""};
, mSelectionArgs[0]
IS set to ""
.
Then later if the mSearchString
is empty (TextUtils.isEmpty(mSearchString)
), then again mSelectionArgs[0]
is assigned ""
.
So the question is that why are they setting it to an empty string when it is already initialized to an empty string?
/*
* This defines a one-element String array to contain the selection argument.
*/
String[] mSelectionArgs = {""};
// Gets a word from the UI
mSearchString = mSearchWord.getText().toString();
// Remember to insert code here to check for invalid or malicious input.
// If the word is the empty string, gets everything
if (TextUtils.isEmpty(mSearchString)) {
// Setting the selection clause to null will return all words
mSelectionClause = null;
mSelectionArgs[0] = "";
} else {
// Constructs a selection clause that matches the word that the user entered.
mSelectionClause = UserDictionary.Words.WORD + " = ?";
// Moves the user's input string to the selection arguments.
mSelectionArgs[0] = mSearchString;
}
...
Except for additional clarity and code readability, as noted in another answer, this coding style makes for a less error prone code which is easier to maintain.
This way, if the initial value of
mSelectionArgs
is changed, or new code added which overrides this value before the execution of theif-else
block, the code of this block will still execute correctly. Without this "rudimentary" assignment, a change as described above could lead to a bug which would be very difficult to trace.As a side note:
This specific code snippet is not that good (yes, I know it is from Android Developers site...) - if you pass
null
asselection
argument toquery()
, then it is better to also passnull
asselectionArgs
argument. I'd modify this sample to something like this (setting bothselection
andselectionArgs
to null):Edit: why the above code snippet is better than the original one?
It is not an error to pass null as
selection
and non-null asselectionArgs
. This array will be passed to the specificContentProvider
you're addressing, and shouldn't be used at all sinceselection
does not contain any?
placeholders. AnyContentProvider
violating this assumption is buggy. Although not an error, it just looks weird - why do you pass an object that should be ignored anyway? This also has performance cost (which is higher ifContentProvider
runs in different process), which is proportional to the size of the object being passed.Edit 2: why the above code snippet is MUCH better than the original one? Turns out that what I said above might be misleading. I found it out the hard way:
The above exception was thrown because I tried to pass
selectionArgs
which contained more elements than the number of?
placeholders inselection
.These two methods from
SQLiteProgram.java
are to "blame" for this exception:Now, when I found out about this behavior, I think that the code example from Android Developers site is not just inefficient, but is a total crap!
Bottom line: if you pass
null
asselection
, passnull
asselectionArgs
as well. Ifselection
is not null and contains?
placeholders - make sure that the length ofselectionArgs
array equals the number of?
placeholders inselection
.