简体   繁体   中英

Update Activity UI from a Timer , after restarting Activity

In the onCreate() method of my activity I have a Timer + TimerTask that will schedule a ParseQuery . On The ParseQuerry callback, which is on mainThread , I delegate an interface callback to make a simple UI update. This works when I let the Activity unchanged. But if I exit from the activity and enter again it (A new timer will NOT be created here, because it gets created only when starting the activity from a certain point) wouldn't work. I think is something with Activity instances but I cannot handle it.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_chat);

       ....
       uiTimer = new Timer();
       uiTask = new TimerTask() {
         @Override
         public void run() {

            doParseTask();
         }
        };
        uiTimer.schedule(uiTask, shortCodeLeft);
    }


    doParseTask(){
      Utils.doParseQuery(this, new MyListener{
      @Override
      public void onSuccess() {
           updateUI();
          }
       });
    }


 updateUI(){

      Log.i(TAG, "Show changed layout"); //This is always shown, this way I ensure it gets here!!
      mTextView.setText(foo); //this doesn't work
      mLayout.setVisibility(View.GONE); //this doesn't work
  }

The ParseQuery is executed in done() callback method, I call the function that updates the UI:

public class Utils{
 .......

   doParseQuery(Context ctx, MyListener listener){
    .......

     query.saveInBackground(new SaveCallback() {
        @Override
        public void done(ParseException e) {
            if(e == null){
                ....
                listener.onSuccess();
            }
        }
    });
  }
}

What I have tried, with no success:

 1. make the `uiTimer` and `uiTask` static global variables; // I thought that maybe it gets leaked into activity instances
    2. update the UI using 
       runOnUiThread(new Runnable() {
                            @Override
                            public void run() {}
                        });

    OR

       mLayout.post(new Runnable() {
                            @Override
                            public void run() {
                                mLayout.setVisibility(View.GONE);
                            }
                        });
3. android:launchMode= "singleInstance" //in Manifest

If you want that your UITimer to gets executed every time your activity goes to foreground, you should implement the onStart or onResume method and move your uiTimer implementation to one of both method. Even your activity being already started these two methods are called after exiting the activity and reopening it again. A better explanation of Android Activity lifecycle is well explained by google documentation https://developer.android.com/guide/components/activities/activity-lifecycle.html .

Your code would look like this:

@Override
protected void onStart() {
   super.onStart();
   ....
   uiTimer = new Timer();
   uiTask = new TimerTask() {
     @Override
     public void run() {

        doParseTask();
     }
    };
    uiTimer.schedule(uiTask, shortCodeLeft);
}


doParseTask(){
  Utils.doParseQuery(this, new MyListener{
  @Override
  public void onSuccess() {
       updateUI();
      }
   });
}

When you exit from your activity, the instances mTextView and mLayout will be destroyed.

Then, when you create a new activity, the activity creates new instances of the text view and layout.

Your timer goes off and tries to update the original elements, which are now invalid as the activity has been closed (but the log still works as this is separate to your activity).

You should initialise the timer & task in onCreate(), and then in order to stop updating the old UI elements:

@Override
protected void onStop() {
    if (uiTimer != null) {
        uiTimer.cancel();
    }
    super.onStop();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM