How use ProgressDialog and Async Task get Method s

2019-05-23 10:00发布

问题:

I have generic async task class which fetches response from server . And i receive those response by using get method . Now i knw that UI thread is block when i use get method , bcoz of which my progress Dialog doesnt showup on time .

Now can someone tell me alternative to do this ?? (In every case i need to send back the response to the activity which has made the call of execute so opening new activity wouldn't help me )

Code : AsyncTask Class

 public class GetDataFromNetwork extends AsyncTask<Void,String,Object> {

protected void onPreExecute() {
    super.onPreExecute();
    progressDialog.show();
} 


 protected Object doInBackground(Void... params) {
    Object result = null;
    try {
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER10);
        new MarshalBase64().register(envelope);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(request);
        AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(ipAddress + webService);
        System.setProperty("http.keepAlive", "true");
        try {
            androidHttpTransport.call(nameSpace + methodName, envelope);
        } catch (Exception e) {

            e.printStackTrace();
            publishProgress(e.getMessage());
        }
        androidHttpTransport.debug = true;
        System.out.println("response: " + androidHttpTransport.requestDump);
        result = envelope.getResponse();
        if(result!=null){
            System.out.println("GetDataFromNetwork.doInBackground() result expection---------"+result);
        }
    } catch (Exception e) {
        System.out.println("GetDataFromNetwork.doInBackground()-------- Errors");
        e.printStackTrace();

    }

    return result;
}

protected void onPostExecute(Object result) {
    super.onPostExecute(result);
    progressDialog.dismiss();
}

Code : Activity

GetDataFromNetwork request = new GetDataFromNetwork(
                                        this,
                                        ProgressDialog.STYLE_SPINNER,
                                        getResources().getText(R.string.autenticate).toString());
response= (SoapObject)request.execute().get();

回答1:

I'm doing stuff like this all the time in my apps and the easiest way I found was to create "Callback" interface and pass it as a parameter to my "AsyncTask"s. You do your "doInBackground()" processing and when it's finished you call the "Callback" instance from onPostExecute passing the "result" object as parameter.

Below is a very simplified version of it.

Example of Callback interface:

package example.app;

public interface Callback {

        void run(Object result);
}

Example of AsyncTask using the Callback interface above:

public class GetDataFromNetwork extends AsyncTask<Void,String,Object> {
  Callback callback;
  public GetDataFromNetwork(Callback callback){
     this.callback = callback;
  }

   protected void onPreExecute() {
      super.onPreExecute();
      progressDialog.show();
  } 


   protected Object doInBackground(Void... params) {
      Object result = null;
      // do your stuff here
      return result;
  }

  protected void onPostExecute(Object result) {
     callback.run(result);
     progressDialog.dismiss();
  }

}

Example of how to use the classes above in your app:

class Example {
   public onCreate(Bundle savedInstanceState){
      //initialize

      GetDataFromNetwork request = new GetDataFromNetwork(new Callback(){
                     public void run(Object result){
                             //do something here with the result
       }});
       request.execute();      
   }
}


回答2:

Like yorkw says, The problem is that you make the UI thread wait for the response with this code:

response= (SoapObject)request.execute().get();

As the documentation for AsyncTask.get() says:

Waits if necessary for the computation to complete, and then retrieves its result.

Since the UI thread waits for the response, it can't show a progress dialog. The solution is to move the code that handles the response to the onPostExecute() method:

protected void onPostExecute(Object result) {
    super.onPostExecute(result);

    // Now we have the response, dismiss the dialog and handle the response
    progressDialog.dismiss();
    response = (SoapObject) result;
}

This method will be invoked after you have the response. Meanwhile, the UI thread can take care of showing a progress dialog.



回答3:

Why don't create another class in which you will put response and in there you will have get and set method. Then in onPostExecute you write it with set method and call a handler where you will do whatever you want...This is just an idea... :)



回答4:

If you are using the AsyncTask, your UI thread won't be blocked. Are you downloading your data inside doInBackground() ? Because that is where you should be doing it.