在android中连接Web服务时显示进度条

时间:2012-12-13 07:45:12

标签: android web-services ksoap2

我想在等待来自Web服务请求的响应时显示进度条。但在此期间,android进度条未加载。

 public class WebService extends Activity {

          private static final String NAMESPACE="http://tempuri.org/";
          private static final String METHOD_NAME="AddEmployee";
          private static final String URL="http://10.32.4.24/Android/AndroidBus.svc";
          private static final String SOAP_ACTION="http://tempuri.org/IAndroidBus/AddEmployee";

          String celsius;
          Button b;
          TextView tv;
          EditText et;
          String res,resultval;

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

             et=(EditText)findViewById(R.id.editText1);        
             tv=(TextView)findViewById(R.id.Result);
             b=(Button)findViewById(R.id.button1);
             b.setOnClickListener(new OnClickListener() {

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

    private class service extends AsyncTask<Void, Void, String> {
         ProgressDialog pd;
         protected void onPreExecute(){
             pd=new ProgressDialog(getBaseContext());
             pd.show();
         }
        @Override
        protected String doInBackground(Void... arg0) {
            System.out.println("In DoIn Background");

            // Initialize soap request + add parameters
            SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);

            PropertyInfo pi=new PropertyInfo();
            pi.setName("Name");
            pi.setValue(et.getText().toString());
            request.addProperty(pi);

                        // Declare the version of the SOAP request
            SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
            envelope.setOutputSoapObject(request);
            envelope.dotNet = true;
            setProgress(1);

            try {
                HttpTransportSE androidHttpTransport = new HttpTransportSE( URL);

                // this is the actual part that will call the webservice
                androidHttpTransport.debug=true;
                androidHttpTransport.call(SOAP_ACTION, envelope);

                String resdump=androidHttpTransport.responseDump.toString();
                System.out.println(resdump);
                setProgress(2);
                // Get the SoapResult from the envelope body.
                //SoapObject result = (SoapObject) envelope.bodyIn;
                SoapPrimitive result=(SoapPrimitive)envelope.getResponse();
                setProgress(3);
                if (result != null) {
                    // Get the first property and change the label text
                    // txtFar.setText(result.getProperty(0).toString());
                    res = result.toString();
                } else {
                    Toast.makeText(getApplicationContext(), "No Response",
                            Toast.LENGTH_LONG).show();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            return res;

        }

        protected void onPostExecute(String h) {
            String result = h;
            pd.dismiss();
            tv.setText(result + "°F");

        }

    }


}

我想在发送和获取请求/响应时显示进度条。

5 个答案:

答案 0 :(得分:2)

你要做的是错的。 SoapSerializationEnvelope,HttpTransportSE和Result之间的进度设置没有任何意义,因为在HttpTransportSE.call(...)中进行了大量的工作。 如果您希望在接收和发送的字节数上真正下载/上传进度条,则必须修改HttpTrasportSE类。详细地说,您必须修改此类的call()和read()。

正如您可以看到here (HttpTransportSE.java),例如,为了实现上传进度,您必须创建HttpTransportSE,复制所有原始代码并修改此部分:

public List call(String soapAction, SoapEnvelope envelope, List headers, File outputFile) throws IOException, XmlPullParserException {
(...)
OutputStream os = connection.openOutputStream();
os.write(requestData, 0, requestData.length);
os.flush();
os.close();
(...)

对此(我考虑过常见的ProgressDialog):

public List call(String soapAction, SoapEnvelope envelope, List headers, File outputFile, ProgressDialog dialog)
    throws IOException, XmlPullParserException {
    (...)

    if(dialog != null)
        {
            dialog.setIndeterminate(false);
            dialog.setProgress(0);

            InputStream iss = new ByteArrayInputStream(requestData, 0, requestData.length);

            int byteCount = 0;
            byte[] buf = new byte[256];
            while (true) 
            {
                int rd = iss.read(buf, 0, 256);
                byteCount += rd;
                if (rd == -1)
                    break;
                os.write(buf, 0, rd);

                dialog.setProgress((int) (((float)byteCount/(float)requestData.length)*100));
            }
            dialog.setIndeterminate(true);

            iss.close();
            buf = null;
        }
        else
            os.write(requestData, 0, requestData.length);

        os.flush();
        os.close();
(...)

正如您所看到的,您必须覆盖调用方法,根据您的目的添加新参数(ProgressDialog或ProgressBar类型)并将其传递给对话框/栏(如果传递'null',则考虑默认逻辑)。 如果您希望进度条显示实际进度(通过ksoap2),这是唯一的方法。

下载时,逻辑是一样的。查找管理下载的代码部分,保存可以从响应头读取的Content-Length值,并考虑以前保存的内容长度,实现类似的上传“while”循环以读取字节。

希望这个解释可以帮到你

答案 1 :(得分:0)

尝试将消息设置为进度对话框..

protected void onPreExecute(){
         pd=new ProgressDialog(WebService.this);
         pd.setMessage("Loading...");
         pd.setIndeterminate(true);
         pd.show();
     }

答案 2 :(得分:0)

你应该在这里尝试不同的上下文对象,

而不是这个,

 ProgressDialog(getBaseContext());

尝试

 ProgressDialog(ActivityName.this);

答案 3 :(得分:0)

我不知道你的setProgress调用是做什么的,但假设它更新了进度对话框,你必须让你的asynctask实现

 protected void onProgressUpdate(Integer... progress) {
     setProgress(progress);
 }

并在publishProgress(2);而不是doInBackground

中致电setProgress

这是因为你无法更新在不同线程上运行的doInBackGround方法中的ui元素。这样做,您不仅可能不会更新对话框,还可能会破坏您的应用程序。

答案 4 :(得分:0)

四步,我们走了......

(1)。您的活动中的 declear进度对话框

private ProgressDialog dialog = null;

(2)。启动AsyncTask类时启动对话框

dialog = ProgressDialog.show(CurrentActivity.this, "", "loading..");

例如

dialog = ProgressDialog.show(CurrentActivity.this, "", "loading search..");

SearchTask task= new GetSearchSeedsData();
task.execute(urlString);

(3)。 在AsyncTask类的doInBackground()方法中执行繁重的工作(web服务或任何)

(4)。 然后在AsyncTask类的onPostExecute()中解除进度对话框

dialog.dismiss();