asynctask中的ProgressBar未在上传时显示

时间:2013-03-22 14:24:42

标签: android android-asynctask progress-bar

有人可以告诉我,为什么在上传图片时没有显示进度条。我从我的旧项目中复制了asynctask结构。在我的旧项目中,我使用asynctask从Web服务器下载图片,并在下载时显示进度条。 这是我的代码:

public class PreviewPostActivity extends Activity {

ImageView imageView;

TextView tvComment;
Button submit;
MyLocationListener locationListener;
List<NameValuePair> list = new ArrayList<NameValuePair>();
private final String url = "***"; //Url of php script
ProgressDialog pDialog;
String responseMessage="";


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.preview_post);

    Intent intent = this.getIntent();
    imageView = (ImageView)findViewById(R.id.imgPerview);
    tvComment = (TextView)findViewById(R.id.txtPreviewComment);
    submit = (Button)findViewById(R.id.btnPreviewSubmit);

    Bitmap image = (Bitmap)intent.getParcelableExtra("picture");
    String comment = intent.getStringExtra("comment");
    locationListener = (MyLocationListener)intent.getSerializableExtra("location");
    String imagePath = intent.getStringExtra("imagePath");
    String date = intent.getStringExtra("date");

    imageView.setImageBitmap(image);
    tvComment.setText(comment);

    //tvComment.append("\n"+locationListener.latitude + "\n"+locationListener.longitude);

    list.add(new BasicNameValuePair("image", imagePath));
    list.add(new BasicNameValuePair("comment", comment));
    list.add(new BasicNameValuePair("longitude", Double.toString(locationListener.longitude)));
    list.add(new BasicNameValuePair("latitude", Double.toString(locationListener.latitude)));
    list.add(new BasicNameValuePair("date", date));

    submit.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            new uploadPost().execute();

        }
    });

}

public void post(List<NameValuePair> nameValuePairs) {
    HttpParams httpParameters = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(httpParameters, 100000);
    HttpConnectionParams.setSoTimeout(httpParameters, 200000);
    HttpClient httpClient = new DefaultHttpClient(httpParameters);
    HttpContext localContext = new BasicHttpContext();
    HttpPost httpPost = new HttpPost(url);

    try {
        MultipartEntity entity = new MultipartEntity();

        for(int index=0; index < nameValuePairs.size(); index++) {
            if(nameValuePairs.get(index).getName().equalsIgnoreCase("image")) {
                // If the key equals to "image", we use FileBody to transfer the data

                entity.addPart(nameValuePairs.get(index).getName(), new FileBody(new File(nameValuePairs.get(index).getValue()),"image/jpeg"));
            } else {
                // Normal string data
                entity.addPart(nameValuePairs.get(index).getName(), new StringBody(nameValuePairs.get(index).getValue()));
            }
        }

        httpPost.setEntity(entity);

        HttpResponse response = httpClient.execute(httpPost, localContext);
        HttpEntity httpEntity = response.getEntity();
        String responseMessage = EntityUtils.toString(httpEntity);

        tvComment.setText(responseMessage);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

class uploadPost extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(PreviewPostActivity.this);
        pDialog.setMessage("Uploading post. Please wait...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    /**
     * Getting product details in background thread
     * */
    protected String doInBackground(String... params) {

        // updating UI from Background Thread
        runOnUiThread(new Runnable() {
            public void run() {

                    //post(list);
                HttpParams httpParameters = new BasicHttpParams();
                HttpConnectionParams.setConnectionTimeout(httpParameters, 100000);
                HttpConnectionParams.setSoTimeout(httpParameters, 200000);
                HttpClient httpClient = new DefaultHttpClient(httpParameters);
                HttpContext localContext = new BasicHttpContext();
                HttpPost httpPost = new HttpPost(url);

                try {
                    MultipartEntity entity = new MultipartEntity();

                    for(int index=0; index < list.size(); index++) {
                        if(list.get(index).getName().equalsIgnoreCase("image")) {
                            // If the key equals to "image", we use FileBody to transfer the data

                            entity.addPart(list.get(index).getName(), new FileBody(new File(list.get(index).getValue()),"image/jpeg"));
                        } else {
                            // Normal string data
                            entity.addPart(list.get(index).getName(), new StringBody(list.get(index).getValue()));
                        }
                    }

                    httpPost.setEntity(entity);

                    HttpResponse response = httpClient.execute(httpPost, localContext);
                    HttpEntity httpEntity = response.getEntity();
                    responseMessage = EntityUtils.toString(httpEntity);

                    //tvComment.setText(responseMessage);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        return null;
    }

    /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) {
        // dismiss the dialog once got all details
        tvComment.setText(responseMessage);
        pDialog.dismiss();
    }
}

因此,当我按下按钮进行上传时,屏幕会冻结并保持冻结,直到上传完成,并且进度条根本不显示。有时它显示,但它的后方,我不知道为什么。我已经尝试从doInBackground体内调用Post()方法,整个代码中的主体(在body中的代码与post()方法中的相同)但效果是相同的,所以我想我在创建进度条时没有做正确的事情。但我再次说我从旧项目中复制了整个asynctask代码,因为它工作得很好。

编辑:

我刚刚尝试在PreviewPostActivity.class的构造函数中创建进度条,之后我为asynctask类创建了构造函数,但它仍然无法正常工作。我很困惑因为它在我的旧程序中起作用。 这是他的代码:

class GetSlike extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(KlubSlikeActivity.this);
        pDialog.setMessage("Ucitavanje u toku. Molimo vas sacekajte...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    /**
     * Getting product details in background thread
     * */
    protected String doInBackground(String... params) {

        // updating UI from Background Thread
        runOnUiThread(new Runnable() {
            public void run() {

                    String id = Integer.toString(k.getId());
                    List<NameValuePair> params = new ArrayList<NameValuePair>();
                    params.add(new BasicNameValuePair("klub",id));

                    slikeUrl = JSONAdapter.getSlike(params);
                    gv.setAdapter(new SlikeAdapter(slikeUrl,KlubSlikeActivity.this));
            }
        });

        return null;
    }

    /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) {
        // dismiss the dialog once got all details
        pDialog.dismiss();
    }
}

唯一改变的是doInBackground body ...

编辑:

执行runOnUiThread()后显示对话框。

2 个答案:

答案 0 :(得分:5)

我发现这个库非常适合完成上传任务,还提供了一个进度处理程序,可以用来设置ProgressBar的值:

https://github.com/nadam/android-async-http

可以像下面这样使用...为上传按钮设置onClickHandler:

@Override
public void onClick(View arg0) {
    try {
        String url = Uri.parse("YOUR UPLOAD URL GOES HERE")
                .buildUpon()
                .appendQueryParameter("SOME PARAMETER IF NEEDED 01", "VALUE 01")
                .appendQueryParameter("SOME PARAMETER IF NEEDED 02", "VALUE 02")
                .build().toString();

        AsyncHttpResponseHandler httpResponseHandler = createHTTPResponseHandler();

        RequestParams params = new RequestParams();
        // this path could be retrieved from library or camera
        String imageFilePath = "/storage/sdcard/DCIM/Camera/IMG.jpg";
        params.put("data", new File(imageFilePath));

        AsyncHttpClient client = new AsyncHttpClient();
        client.post(url, params, httpResponseHandler);
    } catch (IOException e) {
        e.printStackTrace();                
    }
}

然后将此方法添加到您的活动代码中:

public AsyncHttpResponseHandler createHTTPResponseHandler() {
    AsyncHttpResponseHandler handler = new AsyncHttpResponseHandler() {
        @Override
        public void onStart() {
            super.onStart();
        }

        @Override
        public void onProgress(int position, int length) {
            super.onProgress(position, length);

            progressBar.setProgress(position);
            progressBar.setMax(length);
        }

        @Override
        public void onSuccess(String content) {
            super.onSuccess(content);
        }

        @Override
        public void onFailure(Throwable error, String content) {
            super.onFailure(error, content);
        }

        @Override
        public void onFinish() {
            super.onFinish();
        }
    };

    return handler;
}

答案 1 :(得分:3)

在asynctask doinbackground()中运行ui线程不正确。您还在doInBackground()中返回null,并且在onPostExecute()中有参数file_url。 doInbackground()中的返回值在onPostExecute()中接收值。

doInBackGround()在后台运行,因此您无法在此处访问或更新ui。

要更新ui,您可以使用onPostExecute()。

您的AsyncTask应该如下所示。你这样做是错误的。

http://developer.android.com/reference/android/os/AsyncTask.html请参阅“4个步骤”

下的主题
 pd= new ProgressDialog(this);
 pd.setTitle("Posting data");
 new PostTask().execute();

private class PostTask extends AsyncTask<VOid, Void, Void> {

protected void onPreExecute()
{//display dialog.
  pd.show();
}
protected SoapObject doInBackground(Void... params) {
// TODO Auto-generated method stub
       //post request. do not update ui here. runs in background
return null;
}

protected void onPostExecute(Void param)
{   

 pd.dismiss();
 //update ui here
}