【问题标题】:updating horizontal ProgressDialog using Handler, while loading an image from the web使用 Handler 更新水平 ProgressDialog,同时从网络加载图像
【发布时间】:2017-03-15 14:02:32
【问题描述】:

在从网络加载图像时,是否可以使用 Handler(我故意不想使用 AsyncTask)更新水平(确定)ProgressDialog?如果是这样,我该怎么做?

这是 try 块:

URL url = new URL(link);
HttpURLConnection httpCon = (HttpURLConnection)url.openConnection();
if(httpCon.getResponseCode()!=200) return;
InputStream inputStream = httpCon.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
imageView.setImageBitmap(bitmap);

【问题讨论】:

    标签: java android progressdialog android-progressbar


    【解决方案1】:

    是的,这是可能的。您可以通过Message 类传递数据并在HandlerhandleMessage(Message msg) 方法中获取它们,例如这种方式(msg.arg1 - 下载字节数,msg.arg2 - 要下载的总字节数):

    final ProgressDialog progressDialog = new ProgressDialog(this);
    progressDialog.setTitle("Downloading Image ...");
    progressDialog.setMessage("Download in progress ...");
    progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    progressDialog.setProgress(0);
    progressDialog.setMax(100);
    progressDialog.show();
    
    final Handler downloadProgressHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            progressDialog.setProgress(100 * msg.arg1 / msg.arg2);
            if (progressDialog.getProgress() == progressDialog.getMax()) {
                progressDialog.dismiss();
            }
        }
    };
    
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                URL url = new URL("<your_url>");
                HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
                urlConnection.setRequestMethod("GET");
                //urlConnection.setDoOutput(true);
                urlConnection.connect();
                InputStream inputStream = urlConnection.getInputStream();
                int totalSize = urlConnection.getContentLength();
                ByteArrayOutputStream receivedBytesStream = new ByteArrayOutputStream();
                int downloadedSize = 0;
                byte[] buffer = new byte[1024];
                int bufferLength = 0;
                while ((bufferLength = inputStream.read(buffer)) > 0 ) {
                    receivedBytesStream.write(buffer, 0, bufferLength);
                    downloadedSize += bufferLength;
                    Message msg = new Message();
                    msg.arg1 = downloadedSize;
                    msg.arg2 = totalSize;
                    downloadProgressHandler.sendMessage(msg);
                }
                receivedBytesStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    }).start();
    

    或者如果您不想通过msg.arg1msg.arg2 发送数据,您可以创建自定义对象并将其添加到类似msg.obj = new YourCustomObjectClass() // or any other object 的消息中。你可以像这样在handleMessage(Message msg) 方法中得到它:YourCustomObjectClass obj = (YourCustomObjectClass) msg.obj;

    【讨论】:

    • 谢谢安德烈!仅供参考,urlConnection.setDoOutput(true);urlConnection.connect(); 使应用程序崩溃,所以我删除了它们。我还删除了urlConnection.setRequestMethod("GET");,因为HttpURLConnection 默认使用GET 方法......无论如何它现在可以工作了:)
    • 欢迎您!你是对的:urlConnection.setDoOutput(true); 是多余的。
    【解决方案2】:

    不是直接将 InputStream 解码为位图,而是将文件下载到设备中的任何路径。并且从 asynchtask 的 onProgressUpdate 方法中,您可以更新进度。文件下载后打开文件并设置为imageview。

    例如使用异步任务

    class DownloadFileFromURL extends AsyncTask<String, String, String> {
    
        /**
         * Before starting background thread
         * Show Progress Bar Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showDialog(progress_bar_type);
        }
    
        /**
         * Downloading file in background thread
         * */
        @Override
        protected String doInBackground(String... f_url) {
            int count;
            try {
                URL url = new URL(f_url[0]);
                URLConnection conection = url.openConnection();
                conection.connect();
                // getting file length
                int lenghtOfFile = conection.getContentLength();
    
                // input stream to read file - with 8k buffer
                InputStream input = new BufferedInputStream(url.openStream(), 8192);
    
                // Output stream to write file
                OutputStream output = new FileOutputStream("/sdcard/downloadedfile.jpg");
    
                byte data[] = new byte[1024];
    
                long total = 0;
    
                while ((count = input.read(data)) != -1) {
                    total += count;
                    // publishing the progress....
                    // After this onProgressUpdate will be called
                    publishProgress(""+(int)((total*100)/lenghtOfFile));
    
                    // writing data to file
                    output.write(data, 0, count);
                }
    
                // flushing output
                output.flush();
    
                // closing streams
                output.close();
                input.close();
    
            } catch (Exception e) {
                Log.e("Error: ", e.getMessage());
            }
    
            return null;
        }
    
        /**
         * Updating progress bar
         * */
        protected void onProgressUpdate(String... progress) {
            // setting progress percentage
            pDialog.setProgress(Integer.parseInt(progress[0]));
       }
    
        /**
         * After completing background task
         * Dismiss the progress dialog
         * **/
        @Override
        protected void onPostExecute(String file_url) {
            // dismiss the dialog after the file was downloaded
            dismissDialog(progress_bar_type);
    
            // Displaying downloaded image into image view
            // Reading image path from sdcard
            String imagePath = Environment.getExternalStorageDirectory().toString() + "/downloadedfile.jpg";
            // setting downloaded into image view
            my_image.setImageDrawable(Drawable.createFromPath(imagePath));
        }
    
    }
    

    你可以调用它

    new DownloadFileFromURL().execute(link);
    

    【讨论】:

    • 我试图在没有 AsyncTask 的情况下这样做,但还是谢谢!
    猜你喜欢
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 2023-03-30
    • 1970-01-01
    • 2019-05-03
    相关资源
    最近更新 更多