I have a class called MainActivity.java that call an AsyncTask class. The last class have a findViewById() that in execution return this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View <mypackage>.MainActivity.findViewById(int)' on a null object reference
I don't understand how can I edit an ImageView positioned in R.layout.activity_main after that an AsyncTask finish to work.
MainActivity.java
public class MainActivity extends Activity {
    public MainActivity() {}
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new Connection().execute();
    }
}
Connection.java
public class Connection extends AsyncTask<String, Void, String> {
    public String result;
    //I know, this isn't correct, how can i do?
    public MainActivity MainActivity;
    @Override
    protected String doInBackground(String... arg0) {
        // TODO Auto-generated method stub
                //...
        return "a string";
    }
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
                    //...
            // Where the error is generated
            ImageView image = (ImageView) MainActivity.findViewById(R.id.image);
            //...
    }
}
                The error is that
public MainActivity MainActivity;
is never initialized, thus pointing to null. To make your code work the minimum step is in MainActivity
new Connection(this).execute();
In Connection
public class Connection extends AsyncTask<String, Void, String> {
    public MainActivity MainActivity;
    public Connection(MainActivity activity) {
        MainActivity = activity;
    }
But creating a task in onCreate and passing an Activity is not the best idea anyway. Also, field names should always start with a lowercase letter.
The best way is passing an ImageView to the AsyncTask. Don't start a task until the Activity is started and also, don't forget to cancel the task when the Activity is stopped.
public final class MainActivity extends Activity {
    public MainActivity() {}
    private Connection connection;
    private ImageView imageView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.image);
    }
    @Override
    protected void onStart() {
        super.onStart();
        if (connection == null || connection.getStatus() != AsyncTask.Status.RUNNING) {
            connection = new Connection(imageView);
            connection.execute();
        }
    }
    @Override
    protected void onStop() {
        super.onStop();
        if (connection != null && connection.getStatus() == AsyncTask.Status.RUNNING) {
            connection.cancel(true);
        }
    }
}
In Connection.java, store an ImageView as a WeakReference to avoid leaks.
public final class Connection extends AsyncTask<String, Void, String> {
    private final WeakReference<ImageView> imageViewRef;
    public Connection(ImageView view) {
        imageViewRef = new WeakReference<ImageView>(view);
    }
    @Override
    protected String doInBackground(String... arg0) {
        // TODO Auto-generated method stub
                //...
        return "a string";
    }
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
                //...
        final ImageView imageView = imageViewRef.get();
        // if the Activity is still alive, the ImageView will not be null
        if (imageView != null) {
            // set an image or whatever you need
            image.setImageResource(666);
        }
    }
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With