0

I have an application that downloads multiple files (and checks the download speed) within an Asynctask. However, when I am connected to 3G (and there is a handover) or the device switches form WiFi to 3G, my application freezes and I can not handle this problem

@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;
    }

I have read many topics on stackoverflow, however none of them could help me solve the prolem I have with my application. I have the try/catch clause, but it doesn't seem to make a difference. When I am using 3G and the phone connects to annother antenna, or there is a network problem the application freezes. What can I do ?

I have found the problem. It was this line InputStream input = new BufferedInputStream(url.openStream()); I use as inputstream the url. I replaced it with this line: InputStream input = new BufferedInputStream(connection.getInputStream()); Now it seems to work better, when it times-out, the application crashes.

}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();

This is the catch that I use. It seems that when I try to call the within the catch clause the onPostExecute method my application crashes.

protected void onPostExecute(Integer result) {
    Log.d("onpost was called", "here");
messageProgressDialog.setMessage("Your speed is: " + speed +" KBit/sec");
        messageProgressDialog.setCancelable(true);

}

Looking on the Log viewer, only the 1st Log appears. When onPostExecute is called, the app crashes. onPostExecute is never actually executed. Any ideas?

malcolm the4
  • 347
  • 2
  • 5
  • 15

1 Answers1

2

Your problem is likely related to your handling of the return value of input.read(). If a socket is closed, input.read() may return 0 (it may also return -1 in other error situations). If it does return 0, then your loop will hang. I suggest something like:

        while ((count = input.read(data)) > 0) {

That way, your loop will run while you are still making progress on the download.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • Unfortunately it didn't make a difference. The app still freezes. P.S. I added also catch(Exception e) for other exception that I can not think of....but it still freezes/ – malcolm the4 Jun 04 '13 at 01:26
  • So, what does `input.read()` actually return when it "freezes"? – Greg Hewgill Jun 04 '13 at 01:28
  • How can I get this ? Where can I see what input.read() returns ? I am new to android and struggle to learn. – malcolm the4 Jun 04 '13 at 01:42
  • Just print it out using [`Log.d()`](https://developer.android.com/reference/android/util/Log.html), and watch the log entries. – Greg Hewgill Jun 04 '13 at 01:43
  • I put Log.d("error", "The value of count is "+ Integer.toString(count)); inside the while loop, and in the log I can see all the values that count got. the last value is 5904.... the others are 23872 7300 etc. – malcolm the4 Jun 04 '13 at 02:02
  • 1
    Well, then it's hard to say from the code you've given why your app might be freezing. I would suggest the *"when in doubt, print more out"* technique and put `Log.d()` statements throughout your code to try to narrow down the place where things start to go wrong. – Greg Hewgill Jun 04 '13 at 02:07
  • I will look again at my code to see if I am missing something. Hopefully I will figure it out. Thank you for your time Greg! – malcolm the4 Jun 04 '13 at 02:15
  • 1
    I figured it out. I just used one exception handler. catch(Exception e) { exceptions.add(e); Inside the onPostExecute method I iterate the exceptions and display a warning message. Now the application works smooth and does not crash. } and – malcolm the4 Jun 04 '13 at 15:07