. lang。NullPointerException:尝试调用虚拟方法的android.view。查看。mainactivity.findviewbyid (int)'在空对象引用上。

时间:2021-08-19 00:38:28

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

我有一个课叫主活动。调用AsyncTask类的java。最后一个类有一个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 ImageView positioned in R.layout.activity_main after that an AsyncTask finish to work.

我不明白如何编辑一个位于R.layout的ImageView。之后的activity_main将异步任务完成。

MainActivity.java

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

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

            //...

    }
}

4 个解决方案

#1


8  

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。要使代码工作,最基本的步骤是主活动

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中创建任务并传递活动并不是最好的方法。另外,字段名应该总是以小写字母开头。

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。在活动启动之前不要启动任务,并且在活动停止时也不要忘记取消任务。

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.

在连接。java将ImageView存储为弱引用,以避免泄漏。

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

    }

#2


0  

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

        //...

    }
}

#3


0  

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

您没有指定要传递给连接的参数。java AsyncTask。

One of my student is also having same problem. Although he is using Volley Library for HttpConnection (posting data) and main issue was: he is writing URL directly without the http protocol prefix i.e.

我的一个学生也有同样的问题。虽然他正在使用Volley库进行HttpConnection(发布数据),但主要的问题是:他正在直接编写URL,而没有http协议前缀。

String post_url ="api/do_post";

字符串post_url =“api / do_post”;

Simply add http/https at front of your post url:

只需在你的post url前面添加http/https:

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

字符串post_url = " http://api/do_post ";

#4


0  

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.

一旦我换了国旗,它就成功了。

#1


8  

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。要使代码工作,最基本的步骤是主活动

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中创建任务并传递活动并不是最好的方法。另外,字段名应该总是以小写字母开头。

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。在活动启动之前不要启动任务,并且在活动停止时也不要忘记取消任务。

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.

在连接。java将ImageView存储为弱引用,以避免泄漏。

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

    }

#2


0  

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

        //...

    }
}

#3


0  

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

您没有指定要传递给连接的参数。java AsyncTask。

One of my student is also having same problem. Although he is using Volley Library for HttpConnection (posting data) and main issue was: he is writing URL directly without the http protocol prefix i.e.

我的一个学生也有同样的问题。虽然他正在使用Volley库进行HttpConnection(发布数据),但主要的问题是:他正在直接编写URL,而没有http协议前缀。

String post_url ="api/do_post";

字符串post_url =“api / do_post”;

Simply add http/https at front of your post url:

只需在你的post url前面添加http/https:

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

字符串post_url = " http://api/do_post ";

#4


0  

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.

一旦我换了国旗,它就成功了。