NullPointerException异常在线程代码导致线程终止

问题描述:

我已经去按照我的AsyncTask代码:NullPointerException异常在线程代码导致线程终止

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

我的处理程序

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

,当我跑我的应用程序,日志显示此:

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) 

我有一个NullPointer,但我不知道为什么,我跟踪inputstream,fos,size,buf的值,但没有人为null中,空指针出现在用于第二次迭代,特别是在这条线:

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

我跟踪read方法并没有返回null,我在做什么错?我认为我没有使用线程......有什么建议吗?对不起,我的长码,并感谢您的时间

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

我跟踪read方法并没有返回null,我在做什么错?

在我看来,inputStream为空。查看代码后,我看到:

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

所以我怀疑的响应代码不是200。如果响应代码是不是HTTP_OK那么你或许应该回到你的方法和叉线程读取从响应。

在未来,您可以像其他应用程序一样轻松地调试线程应用程序。您可以在NPE附近放置一个断点,然后测试有问题的字段。调试可以搞砸线程程序的时序,但仍然有用。

+0

谢谢但不是,我跟踪了IF条件后的输入流,并且从不为空。 – JaviSanchezG

+0

那么如果响应不是200 @JaviSanchezG,你的代码会发生什么? – Gray

+0

响应总是200,我正在测试与数据连接的应用程序...我认为这是问题,但我打印输入流的值与日志,并且从不为空... @Gray – JaviSanchezG

正如@Gray已经声明的那样,您创建的inputStream为空,并且只在响应为200时为其设置一个值。然后尝试在代码的另一个点访问此对象。

假设您的回答是总是 200不是一种好的做法,因为您每次运行任务时都依赖于连接的成功响应。

您应该为其添加一些错误处理代码,这样您不仅可以避免空指针,而且还可以在出现问题时为用户提供正确的反馈。

我想补充的另一件事是,在使用它之前,您并不需要将inputStream设置为null,因为每个Java对象都已初始化为null。

+1

最后一点只有在实例级初始化它才是真实的。如果它是一个方法变量,那么他当然需要初始化它。 – Gray

+0

是的,谢谢你的回答,我知道不是一个好习惯,我用其他方法验证数据连接。但我仍然得到这个错误,我不知道为什么?现在正在让我疯狂!任何其他建议? @格雷,因为我敢肯定,这不是问题...我认为是一个线程问题或类似的东西... – JaviSanchezG

+0

@JaviSanchezG通过其他方法验证你的意思是在你的'isOnline()'方法?如果是的话,那还不够。即使用户拥有活动连接并通过了验证,但仍有很多可能会返回的响应数量超过200个(并且仍然需要处理)。看看这里。 http://www.w3.org/Protocols/HTTP/HTRESP.html –

感谢您的时间...

的问题已通过删除以下行解决:

inputStream = null; 

这是一个线程的问题,我创建多个线程和我被初始化为InputStream变种而其他线程在哪里运行...

感谢您的帮助和建议家伙!