0
\$\begingroup\$

I want to use the WeakReference approach to not leak memory with my AsyncTask. I found examples online and on Stackoverflow, but they only get the reference in onPostExecute and I am unsure how to correctly use it in all 3 of the UI methods. My current approach is like this, but I have no clue if I can get rid of some redundancy. Why can't I just call activityReference.get() in the constructor and then only check for null in each of the UI methods? Why do the examples online call get right before using the WeakReference?

private static class ExampleAsyncTask extends AsyncTask<Integer, Integer, String> {
 private WeakReference<MainActivity> activityReference;
 ExampleAsyncTask(MainActivity context) {
 activityReference = new WeakReference<>(context);
 }
 @Override
 protected void onPreExecute() {
 super.onPreExecute();
 MainActivity activity = activityReference.get();
 if (activity == null || activity.isFinishing()) {
 return;
 }
 activity.progressBar.setVisibility(View.VISIBLE);
 }
 @Override
 protected String doInBackground(Integer... integers) {
 for (int i = 1; i < integers[0]; i++) {
 try {
 Thread.sleep(1000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 publishProgress((i * 100) / integers[0]);
 }
 return "Finished";
 }
 @Override
 protected void onProgressUpdate(Integer... values) {
 super.onProgressUpdate(values);
 MainActivity activity = activityReference.get();
 if (activity == null || activity.isFinishing()) {
 return;
 }
 activity.progressBar.setProgress(values[0]);
 }
 @Override
 protected void onPostExecute(String s) {
 super.onPostExecute(s);
 MainActivity activity = activityReference.get();
 if (activity == null || activity.isFinishing()) {
 return;
 }
 activity.progressBar.setProgress(0);
 activity.progressBar.setVisibility(View.INVISIBLE);
 Toast.makeText(activity, s, Toast.LENGTH_SHORT).show();
 }
} 
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Mar 11, 2018 at 7:45
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Check for null in WeakReference everytime you need to use it is necessary because the GC process can clear the instance anytime during your work. Besides, onPreExecute, onPostExecute and doInBackground is run in the different thread, there is also some delay when changing thread and the instance may be cleared in between too.

I have a helper method that does the check for null in WeakReference and its instance. Use it if you like:

public <T> T getInstance(WeakReference<T> weakReference) {
 if (weakReference == null || weakReference.get() == null)
 return null;
 // Do more check for your activity if need
 return weakReference.get();
}
answered May 25, 2018 at 7:46
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.