【问题标题】:Progress bar for Multipart uploading with multiple files Android使用多个文件 Android 进行分段上传的进度条
【发布时间】:2012-11-19 18:17:47
【问题描述】:

编辑:已解决,向下滚动;)

按照教程here

我在 AsyncTask 中实现了一个进度条对话框来显示上传数据的百分比。目前它只是从 0% 显示到 100%,然后在所有数据上传之前一直卡在 100%。我正在尝试上传一个 Json 字符串和 4 张图片。

代码:

 private class UploaderTask extends AsyncTask<JSONArray, Integer, String> {

    private ProgressDialog dialog;
    protected Context mContext;
    long totalSize;

    public UploaderTask(Context context) {

        mContext = context;
    }

    @Override
    protected void onPreExecute() {

        dialog = new ProgressDialog(mContext);
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.setTitle("Uploading data");
        dialog.setCancelable(false);
        //dialog.setIndeterminate(true);
        dialog.setMessage("Please wait...");
        dialog.show();
        //dialog.setProgress(0);

    }

    @Override
    public String doInBackground(JSONArray... json) {

        String responseMessage = "";
        int counter = 0;

        try {

            CustomMultiPartEntity entity = new CustomMultiPartEntity(new ProgressListener() {
                @Override
                public void transferred(long num) {
                    publishProgress((int) ((num / (float) totalSize) * 100));
                }
            });

            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(URL);

            //convert JSON array to String (first element contains the whole of data)
            String json_encoded_string = json[0].toString();

            //add json data
            entity.addPart("json", new StringBody(json_encoded_string));

            //get all images plus data and add them to the Multipart Entity

            for (images_cursor.moveToFirst(); !images_cursor.isAfterLast(); images_cursor.moveToNext()) {

                counter++;

                //Get image and convert to byte array
                byte[] image_ba = images_cursor.getBlob(images_cursor.getColumnIndex("image"));
                long image_unit_id = images_cursor.getLong(images_cursor.getColumnIndex("unit_id"));
                String image_caption = images_cursor.getString(images_cursor.getColumnIndex("caption"));

                //add image to multipart
                entity.addPart("image" + counter, new ByteArrayBody(image_ba, "image" + counter + ".jpg"));

                //add unit _id to multipart
                entity.addPart("image_unit_id" + counter, new StringBody(String.valueOf(image_unit_id)));

                //add caption to multipart
                entity.addPart("image_caption" + counter, new StringBody(String.valueOf(image_caption)));

            }

                            totalSize = entity.getContentLength();
            httppost.setEntity(entity);

            HttpResponse response = httpclient.execute(httppost);
            InputStream inputStream = response.getEntity().getContent();
            responseMessage = inputStreamToString(inputStream);

            //log out response from server
            longInfo(responseMessage);

        }
        //show error if connection not working
        catch (SocketTimeoutException e) {
            e.printStackTrace();
            responseMessage = "unreachable";

        }

        catch (ConnectTimeoutException e) {
            e.printStackTrace();
            responseMessage = "unreachable";

        }

        catch (Exception e) {
            e.printStackTrace();
            responseMessage = "unreachable";

        }

        return responseMessage;
    }

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

    @Override
    protected void onPostExecute(String result) {

        //result is the response back from "doInBackground"
        dialog.cancel();

        TextView response_holder = (TextView) findViewById(R.id.response);

        //check if there were errors upoloading
        if (result.equalsIgnoreCase("unreachable")) {
            response_holder.setText("Error while uploading...Please check your internet connection and retry.");
            return;
        }

        if (result.equalsIgnoreCase("error saving project data")) {
            response_holder.setText("There was an error on the server saving the project data, please retry.");
            return;
        }

        if (result.equalsIgnoreCase("error saving sites data")) {
            response_holder.setText("There was an error on the server saving the sites data, please retry.");
            return;
        }

        if (result.equalsIgnoreCase("project saved")) {
            response_holder.setText("Data uploaded successfully!");
            return;
        }

        if (result.equalsIgnoreCase("project already exist")) {
            response_holder.setText("This project already exist!");
            return;
        }

    }

 }

我猜它只是计算 json 字符串的总大小,因为它是第一部分......有什么建议吗?

编辑:可能重复,仍然没有解决方案here

编辑:解决了在发布实体之前添加totalSize = entity.getContentLength();,代码已更新

【问题讨论】:

    标签: android progress-bar multipart


    【解决方案1】:

    看看这段代码:

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

    本质上,您只关心第一个进度值。这很好,因为您的代码中可能只有一个。但是您可以通过在代码中添加 publishProgress 语句来发布进度。这可以通过每次完成某件事时推动一个百分比来完成,如下所示:

         int progress_done=20;
         publishProgress(progress_done);
         for (images_cursor.moveToFirst(); !images_cursor.isAfterLast(); images_cursor.moveToNext()) {
    
                counter++;
    
                //Get image and convert to byte array
                byte[] image_ba = images_cursor.getBlob(images_cursor.getColumnIndex("image"));
                long image_unit_id = images_cursor.getLong(images_cursor.getColumnIndex("unit_id"));
                String image_caption = images_cursor.getString(images_cursor.getColumnIndex("caption"));
    
                //add image to multipart
                entity.addPart("image" + counter, new ByteArrayBody(image_ba, "image" + counter + ".jpg"));
    
                //add unit _id to multipart
                entity.addPart("image_unit_id" + counter, new StringBody(String.valueOf(image_unit_id)));
    
                //add caption to multipart
                entity.addPart("image_caption" + counter, new StringBody(String.valueOf(image_caption)));
    
                progress_done+=20;
                publishProgress(progress_done);
            }
    

    【讨论】:

    • AsyncTask 文档不是最清楚的。 developer.android.com/reference/android/os/…
    • 是的,我花了很长时间才理解它们是如何工作的。基本上,aSyncTask 旨在同时对大量输入进行操作。据我所知,文件中缺少一条关键信息……
    • 无论如何添加您建议的代码并没有改变任何东西。我明天再去一次:/
    • 我建议你打印出进度值是什么,然后从那里开始。祝你好运!
    • 已解决,totalSize = entity.getContentLength(); 丢失,总大小始终为 0
    猜你喜欢
    • 2011-12-07
    • 1970-01-01
    • 2012-07-17
    • 2015-10-19
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多