下载图像用的AsyncTask(Download images with AsyncTask)

2019-07-17 11:46发布

我真的不知道哪里出了问题我的代码或结构。 我想用的AsyncTask下载图片,并显示出在平均时间进度条。 但我尝试了做几个不同的方式。 它仍然失败,不知道什么地方错了。 我的结构流程

内容识别是一个字符串数组,其存储图像的内容ID。

主要问题:它成功地从该URL下载和存储图像到手机,但下载的图像都是相同的图像。 它应该是不同的图像,这不是我所期待。

次要问题:进度条弹出,而应用程序下载图像,但是进度条没有更新的进展。 它只是保持为0%,并在下载完成后驳回。

我想知道是什么原因,我提到的主要和副屏的问题。 请发表评论或回答,如果你会知道什么是错我的代码。 任何帮助将不胜感激。

if(isSyncSuccess){

     SetConstant.IMAGE_EXIST = 1;
     pDialog = new ProgressDialog(GalleryScreen.this);
     pDialog.setMessage("Downloading file. Please wait...");
     pDialog.setIndeterminate(false);
     pDialog.setProgress(0);
     pDialog.setMax(contentId.length);
     pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
     pDialog.setCancelable(true);


     if (contentId.length>0){
     Log.i(TAG, "contentid.length:" +contentId.length);
         for (int i=0;i<contentId.length;i++){
             if(helper.databaseChecking(useremail, contentId[i])){
                 contentdownload = i;
                 SetConstant.CONTENT_ID = contentId[i]; 

                 String URL = SetConstant.URL_DOWNLOAD_CONTENT+contentId[i];

                 DownloadFile downloadFile = new DownloadFile();
                 downloadFile.execute(URL);


                 }



    private class DownloadFile extends AsyncTask<String, Integer, String>{
    @Override
    protected String doInBackground(String... sUrl){
                Bitmap bm;
                InputStream in;

        try{

            in = new java.net.URL(sUrl[0]).openStream();
            bm = BitmapFactory.decodeStream(new PatchInputStream(in));
            File storage = new File(Environment.getExternalStorageDirectory() + File.separator + "/Image/");
            Log.i(TAG,"storage:" +storage);
            Log.i(TAG,"storage:" +storage.getAbsolutePath());
            if(!storage.exists()){
                storage.mkdirs();

            }
                String FileName = "/"+SetConstant.CONTENT_ID+".jpg"; 
                FileOutputStream fos = new FileOutputStream(storage + FileName);
                bm.compress(Bitmap.CompressFormat.JPEG, 85, fos);

                String filepath = storage + FileName;
                File filecheck = new File (filepath);
                long fileSize = filecheck.length();
                fos.flush();
                fos.close();

                Log.i(TAG, "bm:" +bm);
                Log.i(TAG, "fos:" +fos);
                Log.i(TAG, "filesize:" +fileSize);
                Log.i(TAG, "filepath:" +filepath);


        }
        catch(IOException e1){
                e1.printStackTrace();
                }   

        return null;
    }

    @Override
    protected void onPreExecute(){
        super.onPreExecute();
        pDialog.show();
    }

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

    protected void onPostExecute(String result){
        super.onPostExecute(result);
        pDialog.dismiss();
    }
}

编辑

现在能够下载根据影像的应用程序和进度条的工作,以及! 但是,我有另外一个问题是如何返回错误信息时,应用程序无法完成下载。 目前,当应用程序下载失败就会死机。 我认为,我不要运行它的doInBackground侧内。 但是,在我可以做检查? 任何想法如何作为返回一条错误消息,并要求用户重新尝试,而不是崩溃的应用程序?

Answer 1:

你从没叫过onProgressUpdate您在doInBackGround(...) 请注意,运行多个实例AsyncTask是一个坏主意 。 这里是我的建议:

if(isSyncSuccess){
    SetConstant.IMAGE_EXIST=1;
    pDialog=new ProgressDialog(GalleryScreen.this);
    pDialog.setMessage("Downloading file. Please wait...");
    pDialog.setIndeterminate(false);
    pDialog.setProgress(0);
    pDialog.setMax(contentId.length);
    pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    pDialog.setCancelable(true);

    new DownloadFile().execute();
}

private class DownloadFiles extends AsyncTask<String, Integer, String> {
    @Override
    protected String doInBackground(String... sUrl) {
        Bitmap bm;
        InputStream in;

        if (contentId.length > 0) {
            for (int i = 0; i < contentId.length; i++) {
                if (helper.databaseChecking(useremail, contentId[i])) {
                    contentdownload = i;
                    SetConstant.CONTENT_ID = contentId[i];

                    String URL = SetConstant.URL_DOWNLOAD_CONTENT + contentId[i];
                    //YOUR INTRESTING LOOP HERE.
                    publishProgress(30);
                    //SOME INTRESTING NUMBER FOR PROGRESS UPDATE
                }
            }

            try {
                in = new java.net.URL(sUrl[0]).openStream();
                bm = BitmapFactory.decodeStream(new PatchInputStream(in));
                File storage = new File(Environment.getExternalStorageDirectory() + File.separator + "/Image/");
                Log.i(TAG, "storage:" + storage);
                Log.i(TAG, "storage:" + storage.getAbsolutePath());
                if (!storage.exists()) {
                    storage.mkdirs();

                }
                String FileName = "/" + SetConstant.CONTENT_ID + ".jpg";
                FileOutputStream fos = new FileOutputStream(storage + FileName);
                bm.compress(Bitmap.CompressFormat.JPEG, 85, fos);

                String filepath = storage + FileName;
                File filecheck = new File(filepath);
                long fileSize = filecheck.length();
                fos.flush();
                fos.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPreExecute () {
            super.onPreExecute();
            pDialog.show();
        }

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

        protected void onPostExecute (String result){
            super.onPostExecute(result);
            pDialog.dismiss();
        }
    }
}

当然,这个代码不运行,你需要修复的范围。 但是我想表明的是,你的循环应该是doInBackGround(...)你应该只拥有1个实例AsyncTask在给定的时间对于这种情况,并调用onProgressUpdate()



Answer 2:

主要问题:

SetConstant.CONTENT_ID = contentId[i]; 
String URL = SetConstant.URL_DOWNLOAD_CONTENT+contentId[i];

在这里,你所面临的麻烦。 作为@Sofi软件公司的回答,您使用的是全局变量,是由主线程改变,在另一个线程其值。

次要问题:

  • 如果你想有一个进度条进行更新,则必须更新它的价值;
    它不会自动更新。

你需要下载图像的AsyncTask(从网址下载)。 有效地实现你的功能,你需要做的

  • 创建的AsyncTask下载图像(实现doInBackground下载()),也有一个boolean(说isImageDownloaded)来跟踪如果图像是postExecute成功下载()。
  • 不要忘了启动下载之前还显示进度条
  • 执行您的AsyncTask启动下载
  • 创建android.os.CountDownTimer的扩展以倒计时的最短时间
  • 在方法onFinish()检查您跟踪布尔值,如果是假的,那么你取消的AsyncTask扔你想要的面包/对话框
  • 运行的AsyncTask的multipule实例是不是一个好主意,所以做了一个又一个。 。SERIAL_EXECUTOR:您可以使用executeOnExecutor(),以确保该线程以串行方式,请使用运行在一个Executor执行你的AsyncTask的。

以下资源可以帮助你#

如果你需要下载一个图像,显示在imageview的进度条和负荷

  • https://github.com/koush/UrlImageViewHelper
  • http://developer.aiwgame.com/imageview-show-image-from-url-on-android-4-0.html
  • http://blog.blundell-apps.com/imageview-with-loading-spinner/

如果您需要下载多个文件(在这里,为图像)使用的AsyncTask

  • 问题在下载使用的AsyncTask多个文件
  • 如何取回的AsyncTask任务完成状态
  • 实施进度条在Android文件下载

编辑:

从http://developer.aiwgame.com/imageview-show-image-from-url-on-android-4-0.html

new DownloadImageTask((ImageView) findViewById(R.id.imageView1))
            .execute("http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png"); }

public void onClick(View v) {
    startActivity(new Intent(this, IndexActivity.class));
    finish();

}

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;

    public DownloadImageTask(ImageView bmImage) {
        this.bmImage = bmImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mIcon11 = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon11 = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mIcon11;
    }

    protected void onPostExecute(Bitmap result) {
        bmImage.setImageBitmap(result);
    } }

从在Android的ImageView和进度执行图像下载

 // note that you could also use other timer related class in Android aside from this CountDownTimer, I prefer this class because I could do something on every interval basis
            // tick every 10 secs (or what you think is necessary)
            CountDownTimer timer = new CountDownTimer(30000, 10000) {

                @Override
                public void onFinish() {
                    // check the boolean, if it is false, throw toast/dialog
                }

                @Override
                public void onTick(long millisUntilFinished) {
                    // you could alternatively update anything you want every tick of the interval that you specified
                }

            };

            timer.start()


Answer 3:

在下面一行:

SetConstant.CONTENT_ID = contentId[i];

你是一个全局变量设置为一个值,然后创建基于相同的值的字符串URL,并将其传递给的AsyncTask。 执行,然后当下载完毕后,它创建一个名称是基于全局变量SetConstant.CONTENT_ID的文件。

换句话说,你用的是全局变量,是由主线程改变,在另一个线程其值。 不这样做,你会得到各种奇怪的问题,由于不同的线程在不同的时间更新..在价值或输出文件到的AsyncTask的名字传递。 你能做到这一点在DownloadFile构造,并藏在一个字段中的值。

如果你想有一个进度条进行更新,则必须更新它的价值; 它不会自动更新。 (在doInBackground)在任务期间调用AsyncTask.publishProgress和实施onProgressUpdate更新进度对话框。

[编辑:onProgressUpdate的确堪称UI线程。]



Answer 4:

首先创建一个分隔的类,它允许你到达图像地址

类似以下内容:

公共类ImageDownloader扩展的AsyncTask {

    @Override
    protected Bitmap doInBackground(String... urls) {

        try {

            URL url = new URL(urls[0]);

            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            connection.connect();

            InputStream inputStream = connection.getInputStream();

            Bitmap myBitmap = BitmapFactory.decodeStream(inputStream);

            return myBitmap;

        } catch (Exception e) {

            e.printStackTrace();

        }

        return null;
    }
}

然后,通过创建一个对象可以访问这个类(通过一个按钮调用方法),并执行以下类似的位图的任务:

公共类MainActivity延伸活动{

ImageView downloadedImg;

public void downloadImage(View view) {

    ImageDownloader task = new ImageDownloader();
    Bitmap myImage;

    try {
        myImage = task.execute("YOUR IMAGE ADDRESS ........").get();

        downloadedImg.setImageBitmap(myImage);

    } catch (Exception e) {

        e.printStackTrace();
    }

}  

不要忘记:1 - 定义onCreat方法==> downloadedImg =(ImageView的)findViewById(R.id.imageView)的ImageView的; 2 - 通过一个按钮,用户界面链接你创建的方法==>(公共无效downloadImage(查看视图){})3 - 要求在manifest文件权限



文章来源: Download images with AsyncTask