2

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();
    }
Solace
  • 8,612
  • 22
  • 95
  • 183
  • @MD `ed` is `null` before this line, but we have this line to assign `ed` a `View`, so why the exception! – Solace Nov 26 '14 at 11:56
  • Is `mainActivity` synchronized? – Pedro Oliveira Nov 26 '14 at 11:56
  • 3
    @Zarah you shouldn't do any stuff with ui in doInBackground(), consider to use onProgress() – ar-g Nov 26 '14 at 11:57
  • @PedroOliveira Now this word always confuses me. So `mainActivity` is the instance of the main activity in the app. Now: Inside the main activity, another activity is started in a button-click listener. Inside that second activity, I create an instance of the main activity and pass it like `new SearchTask(new MainActivity()).execute();` to execute the AsyncTask named `SearchTask`, which is implemented as a separate class, and whose constructor assigns the passed instance of the main activity to the `mainActivity` member variable of the `SearchTask`. I hope I answered that question somewhere? – Solace Nov 26 '14 at 12:03
  • 1
    Try printing a simple `mainActivity.toString()` and check if you get a NPE. Also as grub said you shouldn't change the UI on `doInBackground`. – Pedro Oliveira Nov 26 '14 at 12:13
  • 1
    He has already put up a null check for `mainActivity` so it can't throw NPE for that and he is not changing the ui in doInBackground – Rahul Gupta Nov 26 '14 at 12:15
  • R.id.mainSearchActivity_editTextSearch is any of this null? – Ironluca Nov 26 '14 at 12:19
  • @Ironluca That is a resource right. If the R file does not contain a resource, the compiler complains, which it did not. – Solace Nov 26 '14 at 12:29
  • you could try-catch that part of the code and print out the variables to see which is null. – vilpe89 Nov 26 '14 at 12:33
  • @vilpe89 Is there a way to print all the variables, like we would do while debugging, in the `catch` block? – Solace Nov 26 '14 at 12:44

4 Answers4

1

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.

1

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.

G_V
  • 2,396
  • 29
  • 44
0

try this

    @Override 
    protected void onPreExecute() {
        EditText ed=null;
        if (mainActivity!=null) {
            ed = (EditText) mainActivity.findViewById(R.id.mainSearchActivity_editTextSearch);//******NPE
searchQuery = ed.getText().toString();
        } else {
            Log.i(TAG, "mainActivity is the Null culprit.");
        }

    }
Serhii Nadolynskyi
  • 5,473
  • 3
  • 21
  • 20
0

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 the onPostExecute() of your AsyncTask

nobalG
  • 4,544
  • 3
  • 34
  • 72
  • First, I am not *updating* the `EditText`. Second, I did try to do it in `onPreExecute` which did not solve this. Please see the Edit in the question, am I still missing it? – Solace Nov 26 '14 at 12:32
  • Why not getting the reference in the onCreate() method of the activity and then getting the text from it and sending it to the AsyncTask – nobalG Nov 26 '14 at 13:02
  • Because I am not implementing AsyncTask as an inner class, but as a separate class. – Solace Nov 26 '14 at 13:09
  • Why not doing that? It will reduce most of your overhead – nobalG Nov 26 '14 at 13:17