Android: How to update an UI from AsyncTask if AsyncTask is in a separate class?

后端 未结 7 2071
半阙折子戏
半阙折子戏 2020-12-02 12:33

I hate inner class.

I\'ve a main activity who launches a \'short-life\' AsyncTask.

AsyncTask is in a separate file, is not an inner class of

相关标签:
7条回答
  • 2020-12-02 12:50

    The Question has already been answered, still im posting how it should be done i guess..

    Mainactivity class

      public class MainActivity extends Activity implements OnClickListener
        {
    
            TextView Ctemp;
    
            @Override
            protected void onCreate(Bundle savedInstanceState)
            {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                Ctemp = (TextView) findViewById(R.id.Ctemp);
                doConv = (Button) findViewById(R.id.doConv);
                doConv.setOnClickListener(this);
            }
    
            @Override
            public void onClick(View arg0) // The conversion to do
            {
                new asyncConvert(this).execute();
            }
        }
    

    now in the async class

    public class asyncConvert extends AsyncTask<Void, Void, String>
    {
        SoapPrimitive response = null;
        Context context;
    
        public asyncConvert(Context callerclass)
        {
            contextGUI = callerclass;
        }
    .
    .
    .
    .
    protected void onPostExecute(String result)
        {
            ((MainActivity) contextGUI).Ctemp.setText(result); // changing TextView
        }
    }
    
    0 讨论(0)
  • 2020-12-02 12:51

    Using Interface 1) Create one Interface

    public interface OnDataSendToActivity {
        public void sendData(String str);
    }
    

    2) Implements it in your Activity

    public class MainActivity extends Activity implements OnDataSendToActivity{
    
         @Override
         protected void onCreate(Bundle savedInstanceState) {
              new AsyncTest(this).execute(new String[]{"AnyData"}); // start your task
         }
    
         @Override
         public void sendData(String str) {
             // TODO Auto-generated method stub
    
         }
    
    }
    

    3) Create constructor in AsyncTask(Activity activity){} Register your Interface in AsyncTask file and call interface method as below.

    public class AsyncTest extends AsyncTask<String, Integer, String> {
    
        OnDataSendToActivity dataSendToActivity;
        public AsyncTest(Activity activity){
            dataSendToActivity = (OnDataSendToActivity)activity;
        }
    
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            dataSendToActivity.sendData(result);
        }
    
    }
    

    Here, your OnPostExecute will call after all task done by AsyncTask and will get "result" as a parameter, returned by doInBackground(){ return "";}.

    While "dataSendToActivity.sendData(result);" it will call activity's overrided method "public void sendData(String str) {}".

    An edge case to remember: Be sure to pass this, i.e. you current activity's context to AsyncTask and not create another instance of your activity, otherwise your Activity will be destroyed and new one is created.

    0 讨论(0)
  • 2020-12-02 12:52

    Just pass the context (activity or whatever) to your AsyncTask in a constructor and then in onSuccess or onProgressUpdate call whatever you need on the context.

    0 讨论(0)
  • 2020-12-02 13:07

    AsyncTask is always separate class from Activity, but I suspect you mean it is in different file than your activity class file, so you cannot benefit from being activity's inner class. Simply pass Activity context as argument to your Async Task (i.e. to its constructor)

    class MyAsyncTask extends AsyncTask<URL, Integer, Long> {
    
        WeakReference<Activity> mWeakActivity;
    
        public MyAsyncTask(Activity activity) {
           mWeakActivity = new WeakReference<Activity>(activity);
        }
    
     ...
    

    and use when you need it (remember to NOT use in during doInBackground()) i.e. so when you would normally call

    int id = findViewById(...)
    

    in AsyncTask you call i.e.

    Activity activity = mWeakActivity.get();
    if (activity != null) {
       int id = activity.findViewById(...);
    }
    

    Note that our Activity can be gone while doInBackground() is in progress (so the reference returned can become null), but by using WeakReference we do not prevent GC from collecting it (and leaking memory) and as Activity is gone, it's usually pointless to even try to update it state (still, depending on your logic you may want to do something like changing internal state or update DB, but touching UI must be skipped).

    0 讨论(0)
  • 2020-12-02 13:08

    Make an static function in your activity class passing context in it to update your text view and then call this function in your AsynkTask class to update.

    In Activity class: public static void updateTextView(){

    //your code here }

    In AynckTask class call this function.

    0 讨论(0)
  • 2020-12-02 13:08
        /**
         * Background Async Task to Load all product by making HTTP Request
         * */
         public  static class updateTExtviewAsyncTask extends AsyncTask<String, String, String> {
    
            Context context;
            ProgressDialog pDialog;
            String id, name;
    
            String state_id;
    
            //--- Constructor for getting network id from asking method
    
            public  updateTExtviewAsyncTask(Context context,String id,String city) 
            {
                context   = context;
                state_id  = id;
                city_name = city;
            }       
            /* *
             * Before starting background thread Show Progress Dialog
             * */
            @Override
            protected void onPreExecute() 
            {
                super.onPreExecute();
                pDialog = ProgressDialog.show(context, "","Please wait...", true, true);
                pDialog.show();
    
            }
    
            /**
             * getting All products from url
             * */
            protected String doInBackground(String... args) 
            {
                return null;
            }
    
            /**
             * After completing background task Dismiss the progress dialog
             * **/
                protected void onPostExecute(String file_url)  {
    
                         YourClass.UpdateTextViewData("Textview data");
            }
        }
    

    // place this code inside your activity class and also declare updating textview static

        public static void  UpdateTextViewData(String tvData) 
    {
       tv.setText(tvData);
    }
    
    0 讨论(0)
提交回复
热议问题