Trying to improve the source code of my app I've noticed that in many activities I have different AsyncTasks that are doing the same: download from internet a document or an image. So I decided to abstract all that classes in only one that allows me doing all of this.
/*
* Class for downloading documents or images from internet
*/
public class taskDownloader extends AsyncTask<Void,Void,Void>{
// Type of download
static final int DOC = 1;
static final int IMAGE = 2;
public String urlFetch; // Url from download content
public int operation; // 'DOC' or 'IMAGE'
public taskInterface listener; // Notify events
public InputStream file; // Result of downloading a DOC
public Bitmap image; // Result of downloading an IMAGE
/*
* Set listener to events
*/
public void setListener(taskInterface listener){
this.listener = listener;
}
/*
* Download a document by url for example an XML file
*/
public void downloadDoc(String url){
this.urlFetch = url;
this.operation = DOC;
this.execute();
}
/*
* Download an image by url
*/
public void downloadImage(String url){
this.urlFetch = url;
this.operation = IMAGE;
this.execute();
}
@Override
protected Void doInBackground(Void... params) {
// Ask about operation requested
switch(operation){
case DOC:
try{
URL url = new URL(urlFetch);
URLConnection urlCon = url.openConnection();
file= urlCon.getInputStream(); // Saving the file
}catch(Exception e){}
break;
case IMAGE:
// Not yet coded
break;
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Log.d("APP", "Downloaded!");
// Test reading the inputstream and where I get exeception
try{
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
br = new BufferedReader(new InputStreamReader(this.file));
while ((line = br.readLine()) != null) {
sb.append(line);
}
Log.d("APP", sb.toString());
}catch(Exception e){
Log.d("APP", "Error" + e);
}
this.listener.onFinished();
}
public InputStream getInputStream(){
return this.file;
}
}
Well, in addition I have created a simple interface for notifications from the AsynTask to who lunched the task. And is that I don't use this AsyncTask exclusive in Activities also for example in a class that download a XML from internet and store on internal storage where I dont have to make changes on the UI.
public interface taskInterface {
public abstract void onFinished();
}
My problem is that I can't access to the result of download (property "file" by getInputStream() method) because I get Android.os.NetworkOnMainThreadException. For tests, on the onPostExecute() method, I have wrote a few lines to read that InputStream and here a get the problem. But putting the same code on doInBackground() works well. How it is possible? The source of exception come from execute internet code on the UI thread but this lines havent code related to this. It's only BufferedReader and no connection to any place. My connection I have correctly placed on doInBackground but onPostExecute I only reading the result of downloading I'm not connecting a website. :(
// Test reading the inputstream
try{
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
br = new BufferedReader(new InputStreamReader(this.file));
while ((line = br.readLine()) != null) {
sb.append(line);
}
Log.d("APP", sb.toString());
}catch(Exception e){
Log.d("APP", "Error" + e);
}
What is that BufferedReader is connected to the URL? I don't understand if only reads the result previusly downloaded on doInBackground method...
LogCatg
07-16 12:08:05.945: W/ActivityThread(5042): Application com.example.lectorrss is waiting for the debugger on port 8100...
07-16 12:08:05.955: I/System.out(5042): Sending WAIT chunk
07-16 12:08:05.985: I/dalvikvm(5042): Debugger is active
07-16 12:08:06.165: I/System.out(5042): Debugger has connected
07-16 12:08:06.165: I/System.out(5042): waiting for debugger to settle...
07-16 12:08:06.375: I/System.out(5042): waiting for debugger to settle...
07-16 12:08:06.585: I/System.out(5042): waiting for debugger to settle...
07-16 12:08:06.795: I/System.out(5042): waiting for debugger to settle...
07-16 12:08:07.005: I/System.out(5042): waiting for debugger to settle...
07-16 12:08:07.215: I/System.out(5042): waiting for debugger to settle...
07-16 12:08:07.425: I/System.out(5042): waiting for debugger to settle...
07-16 12:08:07.635: I/System.out(5042): debugger has settled (1400)
07-16 12:08:07.745: D/SPLASH_SCREEN_ACTIVITY(5042): Descargando información portales
07-16 12:08:07.745: D/SPLASH_SCREEN_ACTIVITY(5042): Descargado
07-16 12:08:07.865: I/PGA(5042): New SOCKET connection: ample.lectorrss (pid 5042, tid 5058)
07-16 12:08:07.875: I/PGA(5042): New SOCKET connection: ample.lectorrss (pid 5042, tid 5042)
07-16 12:08:07.965: D/dalvikvm(5042): GC_FOR_ALLOC freed 76K, 24% free 7469K/9795K, paused 10ms
07-16 12:08:08.005: I/dalvikvm-heap(5042): Grow heap (frag case) to 12.370MB for 3072012-byte allocation
07-16 12:08:08.015: D/dalvikvm(5042): GC_FOR_ALLOC freed 1K, 19% free 10467K/12803K, paused 10ms
07-16 12:08:08.045: D/dalvikvm(5042): GC_CONCURRENT freed 0K, 19% free 10468K/12803K, paused 0ms+0ms
07-16 12:08:08.235: D/APP(5042): Descargado
07-16 12:08:08.255: D/Error(5042): Errorandroid.os.NetworkOnMainThreadException
EDIT: My really question is why BufferedReader throws the exception if it no connects any place. Only reads a variable where previuly have been filled on doInBackground()