java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View .MainActivity.findViewById(int)' on a null object reference

后端 未结 4 809
青春惊慌失措
青春惊慌失措 2020-12-17 20:25

I have a class called MainActivity.java that call an AsyncTask class. The last class have a findViewById() that in execution retur

4条回答
  •  死守一世寂寞
    2020-12-17 20:52

    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 {
    
        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 {
    
        private final WeakReference imageViewRef;
    
        public Connection(ImageView view) {
            imageViewRef = new WeakReference(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);
            }
    
        }
    

提交回复
热议问题