From the Logcat:
11-26 06:43:40.643: E/AndroidRuntime(1163): FATAL EXCEPTION: AsyncTask #1
...
11-26 06:43:40.643: E/AndroidRuntime(1163): java.lang.RuntimeException: An error occured while executing doInBackground()
...
11-26 06:43:40.643: E/AndroidRuntime(1163): Caused by: java.lang.NullPointerException
...
11-26 06:43:40.643: E/AndroidRuntime(1163): at com.example.mymobiletest.SearchTask.doInBackground(SearchTask.java:134)
Line number 134 is ed = (EditText) mainActivity.findViewById(R.id.mainSearchActivity_editTextSearch);
. Now the execution of this line indicates that mainActivity
(it is an instance of the main activity passed to the constructor of this AsyncTask
) is not null
. So what else could be null
at this line, which is causing the NullPointerException
?
@Override
protected String doInBackground(Void... voidParameters) {
EditText ed=null;
if (mainActivity!=null) {
ed = (EditText) mainActivity.findViewById(R.id.mainSearchActivity_editTextSearch);
} else {
return "mainActivity is the Null culprit.";
}
EDIT:- I do think that since I am not changing the UI in doInBackground()
(but only reading from the UI), so this should not be a problem. But still I tried this in onPreExecute()
since onPreExecute
is executed in the UI thread, but I still get the NPE on the same statement.
@Override
protected void onPreExecute() {
EditText ed=null;
if (mainActivity!=null) {
ed = (EditText) mainActivity.findViewById(R.id.mainSearchActivity_editTextSearch);//******NPE
} else {
Log.i(TAG, "mainActivity is the Null culprit.");
}
searchQuery = ed.getText().toString();
}
You should make your task a static inner class unless you need to run multiple of these tasks at the same time. Then you should just separate the class entirely.
doInBackground performs a task, then returns the result to onPostExecute. This is the intended use for ASynctask's general use.
The difference is doInBackground runs in a completely separate thread via a background process. You have no guarantees when it will run or finish. It can't see the UI thread. onPostExecute however, runs on the UI thread.
What this implies is that your ASyncTask has no guarantee the same MainActivity will remain active. Activies get created and destroyed constantly for reasons not exposed to us programmers. Any change in orientation for example will destroy your MainActivity and recreate it, which means your passed reference is now empty regardless of where in the process it is. It could pass the first null check, then crash on the findViewById. You have NO guarantees what happens outside of onCreate().
If you make it an inner static class and call the edittext in onPostExecute it should work fine because the inner class will get reattached to the new activity instance.
try this
You are doing it
Completely Wrong
You are taking the reference of the UI components in background thread, You must not do that.All such references are taken in the
onCreate()
method of the activity.Whenever you will want to update these UI components,you can do it in theonPostExecute()
of yourAsyncTask
As doInBackground() method runs on a different thread other than main thread, so you should not access UI elements in doInBackground() method. you should access UI elements either in OnProgress() or OnPostExcecute() method.