重新启动活动后,从计时器更新活动UI

时间:2017-01-25 15:22:58

标签: android android-activity timer instance timertask

在我的活动的onCreate()方法中,我有一个Timer + TimerTask来安排ParseQuery。在ParseQuerry上的mainThread回调中,我委托一个接口回调来进行简单的UI更新。当我让Activity保持不变时,这可行。但是如果我从活动中退出并再次输入它(这里不会创建新的计时器,因为它只在从某个点开始活动时才会创建)不起作用。我认为是Activity实例,但我无法处理它。

    @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
  }

ParseQuerydone()回调方法中执行,我调用更新UI的函数:

public class Utils{
 .......

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

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

我尝试了什么,没有成功:

 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

2 个答案:

答案 0 :(得分:0)

如果您希望每次活动进入前台时都能执行UITimer,则应实施onStartonResume方法并将uiTimer实现移至两种方法之一。即使您的活动已经启动,这两种方法在退出活动并再次重新打开后调用。 谷歌文档https://developer.android.com/guide/components/activities/activity-lifecycle.html很好地解释了Android活动生命周期的更好解释。

您的代码如下所示:

@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();
      }
   });
}

答案 1 :(得分:0)

退出活动时,mTextView和mLayout实例将被销毁。

然后,当您创建新活动时,活动会创建文本视图和布局的新实例。

您的计时器熄灭并尝试更新原始元素,这些元素现在因活动已关闭而无效(但日志仍然有效,因为这与您的活动是分开的。)

你应该初始化计时器&在onCreate()中执行任务,然后为了停止更新旧的UI元素:

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