How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?

前端 未结 17 2201
鱼传尺愫
鱼传尺愫 2020-11-21 04:50

I have this two classes. My main Activity and the one that extends the AsyncTask, Now in my main Activity I need to get the result from the OnPostExecute(

相关标签:
17条回答
  • 2020-11-21 05:10

    You need to use "protocols" to delegate or provide data to the AsynTask.

    Delegates and Data Sources

    A delegate is an object that acts on behalf of, or in coordination with, another object when that object encounters an event in a program. (Apple definition)

    protocols are interfaces that define some methods to delegate some behaviors.

    Here is a complete example!!!

    0 讨论(0)
  • 2020-11-21 05:13

    You can try this code in your Main class. That worked for me, but i have implemented methods in other way

    try {
        String receivedData = new AsyncTask().execute("http://yourdomain.com/yourscript.php").get();
    } 
    catch (ExecutionException | InterruptedException ei) {
        ei.printStackTrace();
    }
    
    0 讨论(0)
  • 2020-11-21 05:13

    You can call the get() method of AsyncTask (or the overloaded get(long, TimeUnit)). This method will block until the AsyncTask has completed its work, at which point it will return you the Result.

    It would be wise to be doing other work between the creation/start of your async task and calling the get method, otherwise you aren't utilizing the async task very efficiently.

    0 讨论(0)
  • 2020-11-21 05:15

    I felt the below approach is very easy.

    I have declared an interface for callback

    public interface AsyncResponse {
        void processFinish(Object output);
    }
    

    Then created asynchronous Task for responding all type of parallel requests

     public class MyAsyncTask extends AsyncTask<Object, Object, Object> {
    
        public AsyncResponse delegate = null;//Call back interface
    
        public MyAsyncTask(AsyncResponse asyncResponse) {
            delegate = asyncResponse;//Assigning call back interfacethrough constructor
        }
    
        @Override
        protected Object doInBackground(Object... params) {
    
          //My Background tasks are written here
    
          return {resutl Object}
    
        }
    
        @Override
        protected void onPostExecute(Object result) {
            delegate.processFinish(result);
        }
    
    }
    

    Then Called the asynchronous task when clicking a button in activity Class.

    public class MainActivity extends Activity{
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
    
        Button mbtnPress = (Button) findViewById(R.id.btnPress);
    
        mbtnPress.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
    
                    MyAsyncTask asyncTask =new MyAsyncTask(new AsyncResponse() {
    
                        @Override
                        public void processFinish(Object output) {
                            Log.d("Response From Asynchronous task:", (String) output);
    
                            mbtnPress.setText((String) output);
                       }
                    });
    
                    asyncTask.execute(new Object[] { "Your request to aynchronous task class is giving here.." });
    
    
                }
            });
    
        }
    
    
    
    }
    

    Thanks

    0 讨论(0)
  • 2020-11-21 05:16

    Easy:

    1. Create interface class, where String output is optional, or can be whatever variables you want to return.

      public interface AsyncResponse {
          void processFinish(String output);
      }
      
    2. Go to your AsyncTask class, and declare interface AsyncResponse as a field :

      public class MyAsyncTask extends AsyncTask<Void, Void, String> {
        public AsyncResponse delegate = null;
      
          @Override
          protected void onPostExecute(String result) {
            delegate.processFinish(result);
          }
       }
      
    3. In your main Activity you need to implements interface AsyncResponse.

      public class MainActivity implements AsyncResponse{
        MyAsyncTask asyncTask =new MyAsyncTask();
      
        @Override
        public void onCreate(Bundle savedInstanceState) {
      
           //this to set delegate/listener back to this class
           asyncTask.delegate = this;
      
           //execute the async task 
           asyncTask.execute();
        }
      
        //this override the implemented method from asyncTask
        @Override
        void processFinish(String output){
           //Here you will receive the result fired from async class 
           //of onPostExecute(result) method.
         }
       }
      

    UPDATE

    I didn't know this is such a favourite to many of you. So here's the simple and convenience way to use interface.

    still using same interface. FYI, you may combine this into AsyncTask class.

    in AsyncTask class :

    public class MyAsyncTask extends AsyncTask<Void, Void, String> {
    
      // you may separate this or combined to caller class.
      public interface AsyncResponse {
            void processFinish(String output);
      }
    
      public AsyncResponse delegate = null;
    
        public MyAsyncTask(AsyncResponse delegate){
            this.delegate = delegate;
        }
    
        @Override
        protected void onPostExecute(String result) {
          delegate.processFinish(result);
        }
    }
    

    do this in your Activity class

    public class MainActivity extends Activity {
    
       MyAsyncTask asyncTask = new MyAsyncTask(new AsyncResponse(){
    
         @Override
         void processFinish(String output){
         //Here you will receive the result fired from async class 
         //of onPostExecute(result) method.
         }
      }).execute();
    
     }
    

    Or, implementing the interface on the Activity again

    public class MainActivity extends Activity 
        implements AsyncResponse{
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
    
            //execute the async task 
            new MyAsyncTask(this).execute();
        }
    
        //this override the implemented method from AsyncResponse
        @Override
        void processFinish(String output){
            //Here you will receive the result fired from async class 
            //of onPostExecute(result) method.
        }
    }
    

    As you can see 2 solutions above, the first and third one, it needs to create method processFinish, the other one, the method is inside the caller parameter. The third is more neat because there is no nested anonymous class. Hope this helps

    Tip: Change String output, String response, and String result to different matching types in order to get different objects.

    0 讨论(0)
  • 2020-11-21 05:16

    Create a static member in your Activity class. Then assign the value during the onPostExecute

    For example, if the result of your AsyncTask is a String, create a public static string in your Activity

    public static String dataFromAsyncTask;

    Then, in the onPostExecute of the AsyncTask, simply make a static call to your main class and set the value.

    MainActivity.dataFromAsyncTask = "result blah";

    0 讨论(0)
提交回复
热议问题