Error “NullPointerException” al ejecutar un AsyncTask en Android

Question:

I am working on an Android activity that queries a database to fill a ListView, I leave you the code:

    private class EjecutoConsulta extends AsyncTask<Void,Void,List<Comunicado>>{
    @Override
    protected void onPostExecute(List<Comunicado> datos) {
       if (datos!=null){
           rellenaDatos(datos);
       }
    }

    @Override
    protected List<Comunicado> doInBackground(Void... params) {

        DefaultHttpClient httpclient=new DefaultHttpClient();
        String url="http://192.168.0.193/estructuraNueva/scripts/leerComunicados.php";


        HttpGet httpGet=new HttpGet(url);

        String respuesta;


        JSONObject json=null;
        JSONArray jArray=null;

        try {


            ResponseHandler<String> responseHandler=new BasicResponseHandler();

            respuesta=httpclient.execute(httpGet,responseHandler);
            json=new JSONObject(respuesta);

            jArray=json.getJSONArray("datos");

        }catch (Exception e){


            System.out.println("YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");


        }

        ArrayList<Comunicado> datos=new ArrayList();


        for (int i=0;i<jArray.length();i++){

            JSONObject object=null;

            try {

                object=jArray.getJSONObject(i);

                Comunicado comunicado=new Comunicado(object.getString("id"),object.getString("titulo"),object.getString("texto")
                ,object.getString("imagen"),object.getString("link"));


                datos.add(comunicado);


            }catch (Exception e){
                System.out.println("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV");

            }

        }

        return datos;
    }
}

When I disconnect the server, I get this error:

06-08 09:05:02.413 24754-29704/com.example.oftecnica2.appcorporativa E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.example.oftecnica2.appcorporativa, PID: 24754
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int org.json.JSONArray.length()' on a null object reference
at com.example.oftecnica2.appcorporativa.ComunicadosListado$EjecutoConsulta.doInBackground(ComunicadosListado.java:149)
at com.example.oftecnica2.appcorporativa.ComunicadosListado$EjecutoConsulta.doInBackground(ComunicadosListado.java:100)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818)

I understand that it jumps when not being able to consult, but if I have everything between try{}catch(){} , I don't understand why it stops the app. Any way that even though I can't consult, I keep running like nothing? (Logically with the empty list).

Answer:

You can determine the problem by reviewing the message:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int org.json.JSONArray.length ()' on a null object reference

The problem is caused when you try to access the length() method of the jArray instance which is null.

 for (int i=0;i<jArray.length();i++){
...

It is regularly validated with exception handling.

...
...

ArrayList<Comunicado> datos=new ArrayList();
   try {
        for (int i=0;i<jArray.length();i++){

            JSONObject object=null;

                object=jArray.getJSONObject(i);

                Comunicado comunicado=new Comunicado(object.getString("id"),object.getString("titulo"),object.getString("texto")
                ,object.getString("imagen"),object.getString("link"));


                datos.add(comunicado);

              }
     }catch (Exception e){
              System.out.println("Ocurrion un problema: " + e.getMessage());    
     }              

        return datos;
...
...

This "solves" it, but it is best to avoid that this value is null so as not to cause problems later in the flow of your application.

Any way that even though I can't consult, I keep running like nothing?

I suggest two options, the first: you can perform a validation using a tertiary operator, if it does not find the "data" array, create an empty array and with that you avoid manipulating null values:

//jArray=json.getJSONArray("datos");
   JSONArray  jArray = jObject.has("datos") ? jObject.getJSONArray("datos") : new JSONArray();
 for (int i=0;i<jArray.length();i++){
 ...
 ...

The second: which I consider the most important, is to check why your request does not obtain data or if it contains data, because it does not contain the json array "data".

respuesta=httpclient.execute(httpGet, responseHandler);
json=new JSONObject(respuesta);         
jArray=json.getJSONArray("datos");

The correct solution would be that if no data is found, your request returns the empty "data" array.

Another point that has nothing to do with the question, is that it is recommended to stop using the DefaultHttpClient class for connection, since it is a class marked as obsolete:

DefaultHttpClient httpclient=new DefaultHttpClient();
        String url="http://192.168.0.193/estructuraNueva/scripts/leerComunicados.php";
HttpGet httpGet=new HttpGet(url);

instead use HttpUrlConection , I recommend you see the implementation of this class in the Asynctask of Asynctask answer.

Scroll to Top