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附近放置一个断点,然后测试有问题的字段。调试可以搞砸线程程序的时序,但仍然有用。
正如@Gray已经声明的那样,您创建的inputStream
为空,并且只在响应为200时为其设置一个值。然后尝试在代码的另一个点访问此对象。
假设您的回答是总是 200不是一种好的做法,因为您每次运行任务时都依赖于连接的成功响应。
您应该为其添加一些错误处理代码,这样您不仅可以避免空指针,而且还可以在出现问题时为用户提供正确的反馈。
我想补充的另一件事是,在使用它之前,您并不需要将inputStream
设置为null,因为每个Java对象都已初始化为null。
最后一点只有在实例级初始化它才是真实的。如果它是一个方法变量,那么他当然需要初始化它。 – Gray
是的,谢谢你的回答,我知道不是一个好习惯,我用其他方法验证数据连接。但我仍然得到这个错误,我不知道为什么?现在正在让我疯狂!任何其他建议? @格雷,因为我敢肯定,这不是问题...我认为是一个线程问题或类似的东西... – JaviSanchezG
@JaviSanchezG通过其他方法验证你的意思是在你的'isOnline()'方法?如果是的话,那还不够。即使用户拥有活动连接并通过了验证,但仍有很多可能会返回的响应数量超过200个(并且仍然需要处理)。看看这里。 http://www.w3.org/Protocols/HTTP/HTRESP.html –
感谢您的时间...
的问题已通过删除以下行解决:
inputStream = null;
这是一个线程的问题,我创建多个线程和我被初始化为InputStream变种而其他线程在哪里运行...
感谢您的帮助和建议家伙!
谢谢但不是,我跟踪了IF条件后的输入流,并且从不为空。 – JaviSanchezG
那么如果响应不是200 @JaviSanchezG,你的代码会发生什么? – Gray
响应总是200,我正在测试与数据连接的应用程序...我认为这是问题,但我打印输入流的值与日志,并且从不为空... @Gray – JaviSanchezG