1. Are you ready for the Galaxy S20? Here is everything we know so far!

Thread to UI Handler, best practice ?

Discussion in 'Android Development' started by RLScott, Jan 26, 2019.

  1. RLScott

    RLScott Newbie
    Thread Starter

    I'm trying to clean up some thread to UI communication code. In this application, a Worker thread is supposed to remaining running for the lifetime of the app, especially through screen rotations or other events that cause the main activity to be destroyed and re-created. I want to avoid memory leaks and null pointer references. The only communication that is necessary is to nudge the main activity with a single integer code. Here is a condensed version of the essentials (I think). Any comments on the approach I have taken would be greatly appreciated.

    Code (Text):
    1.  
    2. public class Main extends Activity {
    3.   public static WeakReference<Main> gMain;
    4.   public final static MainHandler gMainHand = new MainHandler();
    5.   private final static Worker worker = new Worker();
    6.  
    7.   private static class MainHandler extends Handler {
    8.     @Override
    9.     public void handleMessage(Message msg) {
    10.       Main mainNow = gMain.get();
    11.       if(mainNow == null)
    12.         return;
    13.       switch(msg.what)
    14.       {
    15.         case 42:
    16.            /* Do stuff refering to Main variables through mainNow */
    17.            break;
    18.       }
    19.     } //..end of handleMessage
    20.   }  //..end of MainHandler class
    21.  
    22.   @Override
    23.   public void onCreate(Bundle savedInstanceState)
    24.   {
    25.     gMain = new WeakRefernce<Main>(this);
    26.   }
    27.  
    28.   /* some time later:*/ worker.start();
    29. }  //..end of Main activity class
    30.  
    31. public class Worker extends Thread {
    32.   public void run()
    33.   {
    34.     /* at some point */  Main.gMainHand.sendEmptyMessage(42);
    35.   }
    36. }  //..end of Worker thread class
    37.  
    38.  
     

    Advertisement

  2. Deleted User

    Deleted User Guest

    Looks like a reasonable approach to me.
     
  3. RLScott

    RLScott Newbie
    Thread Starter

    Here is another way of doing it that has the advantage of being able to post runnables and does not require a custom Handler class extension.

    Code (Text):
    1.  
    2. public class Main extends Activity {
    3.   public static WeakReference<Main> gMain;
    4.   public final Handler handler = new Handler();  //..no longer static or custom
    5.   private final static Worker worker = new Worker();
    6.   Runnable doSomethingToUI;
    7.   @Override
    8.   public void onCreate(Bundle savedInstanceState) {
    9.     gMain = new WeakReference<Main>(this);
    10.     doSomethingToUI = new Runnable() {public void run() {
    11.        /*---something affecting UI---*/
    12.   }};
    13.   }    //..end of onCreate()
    14.   /* some time later:*/ worker.start();
    15. }  //..end of Main activity class
    16. public class Worker extends Thread {
    17.   public void run() {
    18.     //..At some point we may do this:
    19.   Main mainNow = Main.gMain.get();    //..strong reference from WeakReference
    20.   if(mainNow != null){
    21.     mainNow.handler.post(mainNow.doSomethingToUI)};
    22. . . . .
    23. }  //..end of Worker thread class
    24.  
    By fetching the strong reference to Main in the worker thread instead of the static custom Handler class, we now get to access all the non-static members of Main normally without having to use an explicit "nowMain." prefix.
     
  4. Deleted User

    Deleted User Guest

    Or use AsyncTask if you want to do something to the UI from a parallel thread.
     
  5. RLScott

    RLScott Newbie
    Thread Starter

    Does an AsyncTask work when the spawning Activity is destroyed and re-created during a screen rotation? I was under the impression that an AsyncTask holds a strong reference to the Activity that created it, and that postings from the AsyncTask went to that instance. In the case of an Activity re-instantiation during the lifetime of the AsyncTask, the AsyncTask posts its results to a now-dead instance of the spawning Activity, not the instance current active. The only reason the old instance did not go away is because the AsyncTask holds the strong reference to it. Do I have that wrong?
     
  6. Deleted User

    Deleted User Guest

Loading...

Share This Page

Loading...