java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'android.view.View .MainActivity.findViewById(int)'

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22329029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 14:58:50  来源:igfitidea点击:

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

javaandroidandroid-asynctask

提问by Kaos

I have a class called MainActivity.javathat call an AsyncTaskclass. The last class have a findViewById()that in execution return this error:

我有一个叫做MainActivity.javaAsyncTask类,它调用一个类。最后一个类findViewById()在执行时返回此错误:

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 ImageViewpositioned in R.layout.activity_mainafter that an AsyncTaskfinish to work.

我不明白如何ImageView在完成工作R.layout.activity_main后编辑定位AsyncTask

MainActivity.java

主活动.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

连接.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);

            //...

    }
}

采纳答案by Yaroslav Mytkalyk

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

从未初始化,因此指向 null。要使您的代码工作,最少的步骤是在 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.

但是在 onCreate 中创建一个任务并传递一个 Activity 无论如何都不是最好的主意。此外,字段名称应始终以小写字母开头。

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.

最好的方法是将 ImageView 传递给 AsyncTask。在 Activity 启动之前不要启动任务,并且不要忘记在 Activity 停止时取消任务。

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.

在 Connection.java 中,将 ImageView 存储为 WeakReference 以避免泄漏。

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);
        }

    }

回答by Lucian Novac

put imageview as a variable of your class

将 imageview 作为类的变量

private ImageView image;

on your onCreate initialize

在你的 onCreate 初始化

image = (ImageView) findViewById(R.id.image);


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
        //do other stuff with your imageview

        //...

    }
}

回答by silwalprabin

You did not specify what parameter you pass to Connection.java AsyncTask.

您没有指定传递给的参数Connection.java AsyncTask

One of my student is also having same problem. Although he is using Volley Libraryfor HttpConnection(posting data) and main issue was: he is writing URLdirectly without the httpprotocol prefix i.e.

我的一个学生也有同样的问题。尽管他使用Volley Libraryfor HttpConnection(发布数据),主要问题是:他URL直接编写没有http协议前缀,即

String post_url ="api/do_post";

String post_url ="api/do_post";

Simply add http/httpsat front of your post url:

只需http/https在您的帖子网址前面添加:

String post_url ="http://api/do_post";

String post_url ="http://api/do_post";

回答by amit pandya

actually i was working an activity and service application. same problem i also got, in that in bindservice i have used the BIND_IMPORTANT flag instead of using BIND_AUTO_CREATE.

实际上我正在处理一个活动和服务应用程序。我也遇到了同样的问题,因为在 bindservice 中我使用了 BIND_IMPORTANT 标志而不是使用 BIND_AUTO_CREATE。

once i changed the flag it was worked successfully for me.

一旦我更改了标志,它就对我成功了。