J'ai une classe appelée MainActivity.Java qui appelle une classe AsyncTask
. La dernière classe a une findViewById()
qui, en exécution, renvoie cette erreur:
Java.lang.NullPointerException: Attempt to invoke virtual method 'Android.view.View <mypackage>.MainActivity.findViewById(int)' on a null object reference
Je ne comprends pas comment éditer une ImageView
positionnée dans R.layout.activity_main
après que AsyncTask
a fini de fonctionner.
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);
//...
}
}
L'erreur est que
public MainActivity MainActivity;
n’est jamais initialisé, pointant ainsi vers null . Pour que votre code fonctionne, l’étape minimale estin MainActivity
new Connection(this).execute();
En connection
public class Connection extends AsyncTask<String, Void, String> {
public MainActivity MainActivity;
public Connection(MainActivity activity) {
MainActivity = activity;
}
Mais créer une tâche dans onCreate et passer une activité ne sont de toute façon pas la meilleure idée… .. De plus, les noms de champs doivent toujours commencer par une lettre minuscule.
La meilleure façon de passer un ImageView à la AsyncTask . Ne commencez pas une tâche tant que l'activité n'a pas démarrée et n'oubliez pas d'annuler la tâche lorsque l'activité est arrêtée.
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);
}
}
}
Dans Connection.Java, enregistrez un ImageView en tant que référence faible pour éviter les fuites.
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);
}
}
Vous n'avez pas spécifié le paramètre que vous transmettez à Connection.Java AsyncTask
.
Un de mes étudiants a également le même problème. Bien qu'il utilise Volley Library
pour HttpConnection
(enregistrement de données) et que le problème principal était: Il écrit URL
directement sans le préfixe http protocol i.e.
String post_url ="api/do_post";
Ajoutez simplement http/https
au début de votre URL de publication:
String post_url ="http://api/do_post";
mettre imageview comme une variable de votre classe
private ImageView image;
sur votre initialisation 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
//...
}
}
en fait je travaillais une application d'activité et de service. Le même problème que j'ai aussi eu.
une fois que j'ai changé le drapeau, cela a fonctionné avec succès pour moi.