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

前端 未结 17 2141
鱼传尺愫
鱼传尺愫 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:18

    Why do people make it so hard.

    This should be sufficient.

    Do not implement the onPostExecute on the async task, rather implement it on the Activity:

    public class MainActivity extends Activity 
    {
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
    
        //execute the async task 
        MyAsyncTask task = new MyAsyncTask(){
                protected void onPostExecute(String result) {
                    //Do your thing
                }       
    
        }
    
        task.execute("Param");
    
    }
    
    
    }
    
    0 讨论(0)
  • 2020-11-21 05:20

    You can write your own listener. It's same as HelmiB's answer but looks more natural:

    Create listener interface:

    public interface myAsyncTaskCompletedListener {
        void onMyAsynTaskCompleted(int responseCode, String result);
    }
    

    Then write your asynchronous task:

    public class myAsyncTask extends AsyncTask<String, Void, String> {
    
        private myAsyncTaskCompletedListener listener;
        private int responseCode = 0;
    
        public myAsyncTask() {
        }
    
        public myAsyncTask(myAsyncTaskCompletedListener listener, int responseCode) {
            this.listener = listener;
            this.responseCode = responseCode;
        }
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }
    
    
        @Override
        protected String doInBackground(String... params) {
            String result;
            String param = (params.length == 0) ? null : params[0];
            if (param != null) {
                // Do some background jobs, like httprequest...
                return result;
            }
            return null;
        }
    
        @Override
        protected void onPostExecute(String finalResult) {
            super.onPostExecute(finalResult);
            if (!isCancelled()) {
                if (listener != null) {
                    listener.onMyAsynTaskCompleted(responseCode, finalResult);
                }
            }
        }
    }
    

    Finally implement listener in activity:

    public class MainActivity extends AppCompatActivity implements myAsyncTaskCompletedListener {
    
        @Override
        public void onMyAsynTaskCompleted(int responseCode, String result) {
    
            switch (responseCode) {
                case TASK_CODE_ONE: 
                    // Do something for CODE_ONE
                    break;
                case TASK_CODE_TWO:
                    // Do something for CODE_TWO
                    break;
                default: 
                    // Show some error code
            }        
        }
    

    And this is how you can call asyncTask:

     protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            // Some other codes...
            new myAsyncTask(this,TASK_CODE_ONE).execute("Data for background job");
            // And some another codes...
    }
    
    0 讨论(0)
  • 2020-11-21 05:21

    in your Oncreate():

    `

    myTask.execute("url");
    String result = "";
    try {
          result = myTask.get().toString();
    } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
    }catch (ExecutionException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
    

    }`

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

    Hope you been through this , if not please read.

    https://developer.android.com/reference/android/os/AsyncTask

    Depending on the nature of result data, you should choose best possible option you can think of.

    It is a great choice to use an Interface

    some other options would be..

    • If the AsyncTask class is defined inside the very class you want to use the result in.Use a static global variable or get() , use it from outer class (volatile variable if necessary). but should be aware of the AsyncTask progress or should at least make sure that it have finished the task and result is available through global variable / get() method. you may use polling, onProgressUpdate(Progress...), synchronization or interfaces (Which ever suits best for you)

    • If the Result is compatible to be a sharedPreference entry or it is okay to be saved as a file in the memory you could save it even from the background task itself and could use the onPostExecute() method
      to get notified when the result is available in the memory.

    • If the string is small enough, and is to be used with start of an activity. it is possible to use intents (putExtra()) within onPostExecute() , but remember that static contexts aren't that safe to deal with.

    • If possible, you can call a static method from the onPostExecute() method, with the result being your parameter

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

    try this:

    public class SomAsyncTask extends AsyncTask<String, Integer, JSONObject> {
    
        private CallBack callBack;
    
        public interface CallBack {
            void async( JSONObject jsonResult );
            void sync( JSONObject jsonResult );
            void progress( Integer... status );
            void cancel();
        }
    
        public SomAsyncTask(CallBack callBack) {
            this.callBack = callBack;
        }
    
        @Override
        protected JSONObject doInBackground(String... strings) {
    
            JSONObject dataJson = null;
    
            //TODO query, get some dataJson
    
            if(this.callBack != null)
                this.callBack.async( dataJson );// asynchronize with MAIN LOOP THREAD
    
            return dataJson;
    
        }
    
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
    
            if(this.callBack != null)
                this.callBack.progress(values);// synchronize with MAIN LOOP THREAD
    
        }
    
        @Override
        protected void onPostExecute(JSONObject jsonObject) {
            super.onPostExecute(jsonObject);
    
            if(this.callBack != null)
                this.callBack.sync(jsonObject);// synchronize with MAIN LOOP THREAD
        }
    
        @Override
        protected void onCancelled() {
            super.onCancelled();
    
            if(this.callBack != null)
                this.callBack.cancel();
    
        }
    }
    

    And usage example:

    public void onCreate(@Nullable Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
    
             final Context _localContext = getContext();
             SomeAsyncTask.CallBack someCallBack = new SomeAsyncTask.CallBack() {
    
                    @Override
                    public void async(JSONObject jsonResult) {//async thread
                        //some async process, e.g. send data to server...
                    }
    
                    @Override
                    public void sync(JSONObject jsonResult) {//sync thread
                        //get result...
    
                        //get some resource of Activity variable...
                        Resources resources = _localContext.getResources();
                    }
    
                    @Override
                    public void progress(Integer... status) {//sync thread
                        //e.g. change status progress bar...
                    }
    
                    @Override
                    public void cancel() {
    
                    }
    
                };
    
                new SomeAsyncTask( someCallBack )
                                    .execute("someParams0", "someParams1", "someParams2");
    
        }
    
    0 讨论(0)
提交回复
热议问题