Reputation: 143
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
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
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
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