由于Android.os.NetworkOnMainThreadException,设计AsynTask类时出现问题

由于Android.os.NetworkOnMainThreadException,设计AsynTask类时出现问题,android,android-asynctask,Android,Android Asynctask,为了改进我的应用程序的源代码,我注意到在许多活动中,我都有不同的任务在做相同的事情:从互联网下载文档或图像。所以我决定把所有这些类抽象成一个可以让我完成所有这些的类 /* * Class for downloading documents or images from internet */ public class taskDownloader extends AsyncTask<Void,Void,Void>{ // Type of download static

为了改进我的应用程序的源代码,我注意到在许多活动中,我都有不同的任务在做相同的事情:从互联网下载文档或图像。所以我决定把所有这些类抽象成一个可以让我完成所有这些的类

/*
 * 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;
}
}
我的问题是,我无法访问下载结果(getInputStream()方法的属性“file”),因为我得到了Android.os.NetworkOnMainThreadException。对于测试,在onPostExecute()方法上,我写了几行代码来读取InputStream,这里是一个解决问题的方法。但是将相同的代码放在doInBackground()上效果很好。这怎么可能异常源来自UI线程上的执行internet代码,但此行没有与此相关的代码。它只是BufferedReader,与任何地方都没有连接。我的连接已正确放置在doInBackground上,但在PostExecute上,我只读取下载结果,没有连接网站:(

BufferedReader连接到URL的是什么?我不明白是否只读取先前在doInBackground方法上下载的结果

日志

 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

编辑:我真正的问题是,如果BufferedReader没有连接任何位置,为什么它会抛出异常。只读取doInBackground()上以前填充的变量。

您看到的问题是,尽管您通过调用
urlCon.getInputStream()获得对流的引用
,您还没有从流中实际读取。然后将此引用传递给UI线程,然后从中读取,这会导致网络操作获取数据,并收到您描述的异常


如果您将从流读取的调用移动到后台线程,它将解决您的问题。

如何调用asynctask?如果出现异常,请始终在问题中包含logcat。例如,在我的第一个活动中,我缓存了Internet的XML文件。因此,我从这里调用了一个自定义类,在该类中我管理所有的do过程从internet下载XML并存储在内部存储器上。这个类与AsyncTask.Activity->cacheMaker class->AsynkTask通信。关于代码:1)我创建了asynk任务。2) 设置我的自定义侦听器。3) 调用downloadDoc()。(对execute()的调用在我上面提到的downloadDoc()中)我不认为这是重复的。我认为您看到的问题是,尽管您通过调用
urlCon.getInputStream()
获得了对流的引用,但您还没有实际读取流。然后将此引用传递给UI线程,然后从中读取,这会导致网络操作获取数据,然后您会收到所描述的异常。@dave.c完全正确!这就是问题所在!现在我明白发生了什么事我原以为getInputStream()会让用户读取内容,但这只是您所说的,它是一个引用,但不是对内容的完整读取。现在我已经修复了这个问题,我没有将结果保存在InputStream中,而是直接将结果保存为doInBackGround中的字符串。非常感谢你!
    // 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);
    }
 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