0
votes

I am trying to reinforce my knowledge of asyncTask so I followed an tutorial to download an image but i didn't understand things and I am getting an error ArrayOutofBound Index so i'll be thankful if anyone tells me the reason here is the code and please tell me why did he iterate for The progress bar max

    public class MainActivity extends AppCompatActivity {
           ProgressBar progessBar;
           ImageView MyImage;
           private final String IMAGE_URL =    "http://www.101apps.co.za/images/headers/101_logo_very_small.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    MyImage = findViewById(R.id.imageView);
    ImageButton downloaad = findViewById(R.id.imageButton);
    downloaad.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            new downloadFile(MainActivity.this).execute(IMAGE_URL);
        }
    });

}
public class downloadFile extends AsyncTask<String , Integer , String>{
    private  int PROGRESS_BAR_MAX = 100;
    Context context;
    public downloadFile(Context cxt){
         this.context = cxt;
    }
    @Override
    protected String doInBackground(String... strings) {
        String result = "";
        String path = context.getFilesDir() + File.pathSeparator + "downloadFile.png";
        HttpURLConnection httpURLConnection = null;
        try{
            final URL url  = new URL(strings[0]);
            httpURLConnection = (HttpURLConnection) url.openConnection();
            int length = httpURLConnection.getContentLength();
            InputStream IS = (InputStream) url.getContent();
            byte[] imageData = new byte[length];
            Log.d("aho" , "" + length);
            int buffersize = (int) Math.ceil(length/(double)PROGRESS_BAR_MAX);
            int download = 0;
            for(int i = 1 ; i < PROGRESS_BAR_MAX ; i++){
                long read = IS.read(imageData , download , buffersize);
                download += read;
                publishProgress(i);

            }

            BufferedInputStream bufferedReader = new BufferedInputStream(httpURLConnection.getInputStream());
            FileOutputStream Fo = new FileOutputStream(path);
            int data = bufferedReader.read();
            while(data != -1){
                Fo.write(data);
                data = bufferedReader.read();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(httpURLConnection == null){
                httpURLConnection.disconnect();
            }
        }
        publishProgress(PROGRESS_BAR_MAX);
        return path;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progessBar = findViewById(R.id.progressBar);
        progessBar.setMax(PROGRESS_BAR_MAX);


    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        progessBar.setProgress(values[0]);
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        if(s != null) {
            progessBar.setVisibility(View.INVISIBLE);
            Bitmap bitmap = BitmapFactory.decodeFile(s);
            MyImage.setImageBitmap(bitmap);

        }
    }
}
}

here is the stack trace 01-20 03:37:40.607 4075-4096/com.gamecodeschool.bodybuilder E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1 Process: com.gamecodeschool.bodybuilder, PID: 4075 java.lang.RuntimeException: An error occurred while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:353) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383) at java.util.concurrent.FutureTask.setException(FutureTask.java:252) at java.util.concurrent.FutureTask.run(FutureTask.java:271) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) Caused by: java.lang.ArrayIndexOutOfBoundsException: size=1123 offset=1116 byteCount=12 at com.android.okhttp.okio.Util.checkOffsetAndCount(Util.java:29) at com.android.okhttp.okio.RealBufferedSource$1.read(RealBufferedSource.java:368) at com.gamecodeschool.bodybuilder.MainActivity$downloadFile.doInBackground(MainActivity.java:66) at com.gamecodeschool.bodybuilder.MainActivity$downloadFile.doInBackground(MainActivity.java:45) at android.os.AsyncTask$2.call(AsyncTask.java:333) at java.util.concurrent.FutureTask.run(FutureTask.java:266)

1
You should always post the stacktrace when you get a runtime exception. - codeMagic
Your error may be because the InputStream at httpUrlConnection.getContentLenght() returns -1 instead of the actual size. So you can never fit your content inside the byte[] imageData, there's other implementations that doesn't requires knowing the original size before reading the content. - Marcos Vasconcelos
@codeMagic okey i'll poost it - moumenShobakey
@MarcosVasconcelos no i checked that it returns the actual size i'll post the stacktrace immediately - moumenShobakey

1 Answers

0
votes

It's because your read loop is looping over the progress count rather than the size of the resource it is downloading. Loop over the size of the resource (be sure to check for read errors) and calculate the progress based on the amount read vs the total length.