由于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