java - traducir - NullPointerException al intentar pasar una matriz de cadenas de una clase a otra
que es un nullpointerexception en java (2)
En este tipo de situaciones, necesita hacer uso de devoluciones de llamada . No puede llamar a execute()
de una AsyncTask
y de inmediato comienza a usar el valor devuelto porque AsyncTask
ejecuta en un subproceso separado y tendrá el problema de concurrencia mencionado por @inmyth y otros en los comentarios.
Entonces, lo que debes hacer para que funcione es utilizar devoluciones de llamada. Al principio, esto podría parecer una solución exagerada, pero créanme, vale la pena cuando intentan implementar grandes proyectos.
En primer lugar, declare una interfaz de escucha dentro de su clase HarvesterAsync
y puede implementar estos oyentes donde quiera obtener el valor de la AsncTask
Aquí hay una muestra:
public class HarvesterAsync extends AsyncTask<...> {
// declare your variables
private List<HarvesterAsyncListener> harvestListeners;
public HarvesterAsync() {
// initialise all variables
harvestListeners = new ArrayList<HarvestAsyncListener>();
}
@Override
protected void doInBackground() {
// ...
// fetch your data from somewhere and load it into say "metaData"
String[] metaData = fetchYourData();
// notify all listeners that the data has been successfully fetched
for(listener: harvestListeners) {
// pass in your result to the method of the interface
listener.onFetchComplete(metaData);
}
}
// use this method to add new listeners to harvestListeners
public void addListener(HarvestListener listener) {
harvestListeners.add(listener);
}
public interface HarvestAsyncListener {
public void onFetchComplete(String[] metaData);
}
}
Ahora para obtener el resultado, puede implementar la interfaz de escucha de esta manera:
public class MetaDataFetcher implements HarvesterAsync.HarvesterAsyncListener {
String[] metaData;
public void getMetaData() {
// initailize the AsyncTask
HarvestAsync harvestAsnc = new HarvestAsync();
// add the listener
harvestAsync.addListener(this);
...
}
@Override
public void onFetchComplete(String[] metaData) {
// do whatever you want with metaData.
this.metaData = metaData;
....
}
}
Por supuesto, puede cambiar la firma del método en la interfaz para adaptarla a sus requisitos.
Aquí no es necesario que devuelva los metaData
porque una vez que los carga AsyncTask
, AsyncTask
realiza una devolución de llamada a onFetchComplete
.
En mi aplicación de Android, hay algunas cadenas que necesito usar en dos lugares diferentes en mi aplicación. Entonces escribí una clase de la cual puedo obtener estas cadenas. Cuando intento llamar al método de devolución de la clase que devuelve el conjunto de cadenas, la aplicación se bloquea con java.lang.NullPointerException
. Aquí está la clase con el método de retorno:
public class MetaDataFetcher {
String[] metaData;
public String[] getMetaData() {
//Gets the metadata strings from HarvasterAsync
try {
metaData = new HarvesterAsync().execute("urlhere").get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return metaData;
}
}
Estoy intentando recuperar la matriz de cadenas de esta manera:
public void updateMetaData(){
//Gets the metadata strings from MetaDataFetcher
String[] receivedMetaData = metaDataFetcher.getMetaData();
//More code below...
La NullPointerException se produce en la línea String[] receivedMetaData = metaDataFetcher.getMetaData();
.
¿Qué estoy haciendo mal?
Editar:
Inicializo la clase MetaDataFetcher
con la línea MetaDataFetcher metaDataFetcher;
sobre el método onCreate en mi clase MainActivity
.
HarvesterAsync es una AsyncTask
. Puedes verlo aquí .
El problema es la concurrencia. AsyncTask no es bloqueante. Así que básicamente esto
String[] receivedMetaData = metaDataFetcher.getMetaData();
devolverá inmediatamente el recibidoMetaData del campo de MetaDataFetcher no el resultado de HarvesterAsync.