我有一个在Asynctask中下载多个文件(并检查下载速度)的应用程序。但是,当我连接到3G(并且有切换)或设备从WiFi切换到3G时,我的应用程序冻结,我无法处理这个问题
@Override
protected Integer doInBackground(String... sUrl) {
try {
speed=0; //initial value
int i=0;
while ((i<sUrl.length)) {
URL url = new URL(sUrl[i]);
URLConnection connection = url.openConnection();
connection.setReadTimeout(10000);
connection.connect();
int fileLength = connection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(file);
byte data[] = new byte[1024*1024]; //1MB buffer
long total = 0;
int count;
long start = System.currentTimeMillis();
while ((count = input.read(data)) != -1) {
total += count;
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
long finish = System.currentTimeMillis();
long tempSpeed= (fileLength *8)/(finish-start);
if (tempSpeed>speed) {
speed=tempSpeed;
}
output.flush();
output.close();
input.close(); // connection is closed
i++;
}
}catch(SocketTimeoutException e) {
exceptions.add(e);
messageProgressDialog.setCancelable(true);
AlertDialog alertDialog;
alertDialog = new AlertDialog.Builder(gui.getActivity()).create();
alertDialog.setTitle("Network problem");
alertDialog.setMessage("connection dropped");
alertDialog.show();
} catch (IOException e) {
exceptions.add(e);
messageProgressDialog.setCancelable(true);
AlertDialog alertDialog;
alertDialog = new AlertDialog.Builder(gui.getActivity()).create();
alertDialog.setTitle("IOException");
alertDialog.setMessage("IOException error");
alertDialog.show();
} catch(Exception e) {
exceptions.add(e);
AlertDialog alertDialog;
alertDialog = new AlertDialog.Builder(gui.getActivity()).create();
alertDialog.setTitle("Exception");
alertDialog.setMessage("Exception error");
alertDialog.show();
}
return 1;
}
我已经阅读了很多关于stackoverflow的主题,但是没有一个可以帮助我解决我的应用程序问题。我有try / catch子句,但它似乎没有什么区别。当我使用3G并且手机连接到另一个天线时,或者存在网络问题时应用程序冻结。我该怎么办?
我发现了这个问题。这条线InputStream input = new BufferedInputStream(url.openStream());
是我用作输入流的网址。我用这一行替换了它:InputStream input = new BufferedInputStream(connection.getInputStream());
现在看起来效果更好,当它超时时,应用程序崩溃了。
}catch(SocketTimeoutException e) {
String erro=Integer.toString(count);
Log.d("error socketTimeout",erro);//1st log
exceptions.add(e);
onPostExecute(1);
Log.d("error sockteTimeout", "here"); //2nd log to see if onPostExecute worked
AlertDialog alertDialog;
alertDialog = new AlertDialog.Builder(gui.getActivity()).create();
alertDialog.setTitle("Network problem");
alertDialog.setMessage("connection dropped");
alertDialog.show();
这是我使用的捕获物。似乎当我尝试在catch子句中调用onPostExecute方法时,我的应用程序崩溃了。
protected void onPostExecute(Integer result) {
Log.d("onpost was called", "here");
messageProgressDialog.setMessage("Your speed is: " + speed +" KBit/sec");
messageProgressDialog.setCancelable(true);
}
查看日志查看器,仅显示第一个日志。当调用onPostExecute时,应用程序崩溃。 onPostExecute从未实际执行过。 有什么想法吗?
答案 0 :(得分:2)
您的问题可能与您对input.read()
的返回值的处理有关。如果套接字关闭,input.read()
可能返回0(在其他错误情况下它也可能返回-1)。如果它确实返回0,那么你的循环将挂起。我建议像:
while ((count = input.read(data)) > 0) {
这样,您的循环将在您仍在下载中取得进展时运行。