JaviSanchezG
JaviSanchezG

Reputation: 143

NullPointerException in thread code causing thread to terminate

I have de following code in my Asynctask:

public DialogoAlerta dialogo;
    public FileOutputStream fos;
    public int size;
    public byte[] buf;
    public int byteRead;
    public int bytesDownloaded;
    public InputStream inputStream;
    public int time;
    public Thread hilo;

    @Override
    protected Boolean doInBackground(Void... arg0) {

        readXML();

        db = bdhelper.getWritableDatabase();

        if(db != null)
        {
            Log.d("Tamaño de la lista", buttonsList.size()+"");

for(int i=0; i<buttonsList.size(); i++)
            {
                String[] campos = new String[] {"local"};
                String[] args = new String[] {buttonsList.get(i).getImageurl().toString()};
                Cursor c = db.query("Imagenes", campos, "url=?", args, null, null, null);
                Cursor c2 = db.rawQuery("SELECT url, local FROM Imagenes WHERE url='"+args+"' AND local='imagemissing.png'", null);
                Log.d("El valor de la consulta es: ", "valor "+c.moveToFirst());
                if (!c.moveToFirst() || (c.moveToFirst() && c2.moveToFirst())){
                    if(isOnline()){
                    //Generamos los datos
                        Random generator = new Random();
                        int n = 10000;
                        n = generator.nextInt(n);

                        String url = buttonsList.get(i).getImageurl().toString();
                        String local = "Imagen" + n;
                        try {
                            URL direccion = new URL(url);
                            File myDir =  new File(Environment.getExternalStorageDirectory () +"/Aspaceimages/");

                            if(!myDir.exists()){
                                myDir.mkdirs();
                                Log.v("", "Se crea la ruta "+myDir);
                            }

                            File file = new File (myDir, local+".jpg");
                            while(file.exists()){
                                local = local + n;
                                file = new File(myDir, local+".jpg");
                            }

                            URLConnection ucon = direccion.openConnection();
                            inputStream = null;
                            HttpURLConnection httpConn = (HttpURLConnection)ucon;
                            httpConn.setRequestMethod("GET");
                            httpConn.connect();
                            Log.d("Peso de la imagen en Bytes (header): ", httpConn.getContentLength()+"");


                          if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                           inputStream = httpConn.getInputStream();
                          }

                            fos = new FileOutputStream(file);
                            size = 1024*1024;
                            buf = new byte[size];
                            bytesDownloaded = 0;

                            hilo = new Thread(new Runnable() {

                                @Override
                                public void run() {
                                    // TODO Auto-generated method stub
                                    try {
                                        Log.i("ID DEL HILO", hilo.getId()+"****************************");
                                        while (((byteRead = inputStream.read(buf)) != -1)) {
                                            fos.write(buf, 0, byteRead);
                                            bytesDownloaded += byteRead;
                                            Log.d("leyendo imagen", "descargando imagen del servidor");
                                        }
                                        Log.d("peso de la imagen descargada", ""+bytesDownloaded);
                                        fos.close();
                                        Message msg = new Message();
                                          msg.what = IMAGE_DOWNLOADED;
                                          mHandler.sendMessage(msg);
                                    } catch (IOException e) {
                                        Log.e("Error", "not downloading");
                                        e.printStackTrace();
                                    }

                                }
                            });
                            hilo.start();   



                            //Compruebo si hay conexión accediendo al tipo de contenido
                                if(!httpConn.getContentType().toString().contains("image")){
                                    db.execSQL("DROP TABLE Imagenes");
                                    Log.d("Eliminada: ", "Base de datos eliminada");
                                    db.execSQL("CREATE TABLE IF NOT EXISTS Imagenes (url TEXT, local TEXT)");
                                    deleteDirectory(myDir);
                                    return false;   
                                }




                        } catch (MalformedURLException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }catch (Exception e) {
                            e.printStackTrace();                            
                        }

                        if(!c.moveToFirst()){
                            //Insertamos los datos en la tabla Usuarios
                            db.execSQL("INSERT INTO Imagenes (url, local) " +
                                       "VALUES ('" + url + "', '" + local+".jpg" +"')");
                            Log.i("Inserta en la base de datos", "Inserta");
                        } else if (c.moveToFirst() && c2.moveToFirst()){
                            //Actualizamos el registro en la base de datos
                            db.execSQL("UPDATE Imagenes SET local='"+local+".jpg' WHERE url='"+url+"'");
                            Log.i("Actualiza en la base de datos", "Actualiza");
                        }
                        publishProgress((100/buttonsList.size())*(i+1));
                    } else {
                        Log.d(tag, "error");
                        db.execSQL("DROP TABLE Imagenes");
                        Log.d("Eliminada: ", "Base de datos eliminada");
                        db.execSQL("CREATE TABLE IF NOT EXISTS Imagenes (url TEXT, local TEXT)");
                        return false;
                    }
                } else {
                    try {
                        Thread.sleep(100);
                    } catch(InterruptedException e) {}
                    publishProgress((100/buttonsList.size())*(i+1));
                }
            }

my handler

public Handler mHandler = new Handler() {
        public void handleMessage(Message msg){
            switch (msg.what){
                case IMAGE_DOWNLOADED : {
                    Log.d("Imagen descargada", "entró al handler");
                    try {
                        Thread.sleep(2000);
                    } catch(InterruptedException e) {}
                    break;
                }
                default : {
                    break;
                }
            }
        }
    };

and when i run my app, the log show me this:

01-16 16:39:27.941: W/dalvikvm(14273): threadid=14: thread exiting with uncaught exception (group=0x41850ba8)
01-16 16:39:27.951: E/AndroidRuntime(14273): FATAL EXCEPTION: Thread-415
01-16 16:39:27.951: E/AndroidRuntime(14273): Process: com.example.aspace, PID: 14273
01-16 16:39:27.951: E/AndroidRuntime(14273): java.lang.NullPointerException
01-16 16:39:27.951: E/AndroidRuntime(14273):    at com.example.aspace.SplashActivity$MiTareaAsincrona$2.run(SplashActivity.java:312)
01-16 16:39:27.951: E/AndroidRuntime(14273):    at java.lang.Thread.run(Thread.java:841)

i have a NullPointer but i don't know why, i tracked the values of inputstream, fos, size, buf but no one is null, the nullpointer appears on the for second iteration, specifically on this line:

while (((byteRead = inputStream.read(buf)) != -1)) {

I tracked the read method and doesn't return null, what am i doing wrong? I think am not using the Thread well... any suggestions? sorry for my long code and thanks for your time

Upvotes: 0

Views: 193

Answers (3)

JaviSanchezG
JaviSanchezG

Reputation: 143

thank you for your time...

The problem has been resolved by deleting the following line:

inputStream = null;

It was a Thread problem, I create multiple Threads and i was initializing inputstream var while other Threads where running...

Thanks for your help and suggestions guys!

Upvotes: 0

fehbari
fehbari

Reputation: 1449

As @Gray has already stated, you're creating your inputStream as null and only setting a value to it when the response is 200. Then you try to access this object in another point of your code.

Assuming that your response is always 200 is not a good practice, since you're relying on a successful response from the connection everytime your task runs.

You should add some error treatment code to it, so you not only avoid null pointers but can also give the user proper feedback when something goes wrong.

One more thing I'd like to add is, you don't really need to set inputStream as null before you use it, since every Java object is already initialized as null.

Upvotes: 0

Gray
Gray

Reputation: 116878

while (((byteRead = inputStream.read(buf)) != -1)) {

I tracked the read method and doesn't return null, what am i doing wrong?

Looks to me that the inputStream is null. After looking at the code I see:

inputStream = null;
...
if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
    inputStream = httpConn.getInputStream();
}
...
// thread does the read

So I suspect the response code is not 200. If the response code is not HTTP_OK then you should probably return out of your method and not fork a thread to read from the response.

In the future you can easily debug threaded applications the same as you can other applications. You can just put a breakpoint near the NPE and then test the fields in question. Debugging can screw up the timing of the threaded programs but is still useful.

Upvotes: 1

Related Questions