簡體   English   中英

銷毀后,AsyncTask 不會在恢復片段中更新我的文本視圖

[英]AsyncTask does not updating my textview in resume fragment after destroy

我在后台運行一個包含計時器的線程,我在TextView中顯示這個計時器,但是當我更改當前片段並返回仍在logcat中運行但不在 UI 中更新的計時器時

我的代碼:

final Runnable r = new Runnable() {
            public void run() {
                if (mBound) {
                    long elapsedTime = stopWatchService.getElapsedTime();
                    formattedTime = DateUtils.formatElapsedTime(elapsedTime);
                    Log.i(TAG, "formattedTime "+ formattedTime);
                    textView.setText(formattedTime);
                }
            }
        };
 Task task = new Task(r);
 task.execute((Void) null);

我的任務:

public class Task extends AsyncTask<Void, Void, Void> {


        private static final String TAG = "Task";

        private boolean mPaused;

        private Runnable mRunnable;

        public Task(Runnable runnable, TextView textView) {
            mRunnable = runnable;
            play();


        }

        @Override
        protected Void doInBackground(Void... params) {
            while (!isCancelled()) {
                if (!mPaused) {

                    mRunnable.run();
                    sleep();
                }
            }
            return null;
        }

        private void sleep() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Log.w(TAG, e.getMessage());
            }
        }

        public void play() {
            mPaused = false;
        }

        public void pause() {
            mPaused = true;
        }

        public void stop() {
            pause();
            cancel(true);
        }

        public boolean isPaused() {
            return mPaused;
        }
}

我的服務:

public class StopWatchService extends Service {

    private String TAG = "walkingApp";
    StopWatch stopWatch = new StopWatch();

    public StopWatchService() {

    }

    public class LocalBinder extends Binder {
        public StopWatchService getService() {
            return StopWatchService.this;
        }
    }

    private final IBinder mBinder = new LocalBinder();


    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    /*
    When the service is started, start stopwatch.
     */
    public int onStartCommand(Intent intent, int flags, int startId) {
        stopWatch.start();


        return START_STICKY;
    }

    /* return how much time has passed in seconds */
    public long getElapsedTime() {
        return stopWatch.getElapsedTime();
    }


    @Override
    public boolean stopService(Intent name) {
        stopWatch.stop();
        return super.stopService(name);

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
       // stopWatch.stop();
    }
}

AsyncTask 幾年前就被棄用了,恕我直言,早就該棄用了。 它有很多問題,就像你遇到的那個,而且只有在一些非常特殊的情況下才能真正發揮作用。

還有其他幾種方法可以處理這種情況,包括但不限於 RxJs、executor 和 Kotlin Coroutines。

查看Android 11 中棄用的 AsyncTask API。有哪些替代方案?

這里的簡短回答可能是您使用Chronometer而不是TextView 然后您需要做的就是設置一次開始時間,您不再需要擔心跟蹤顯示自己的時間。 你可以擺脫你的計時器。 例如(非常天真的方法):

public class MyActivityOrFragment ... {

  //Start time as "uptime"
  private static final AtomicLong base = 
    new AtomicLong(SystemClock.uptimeMillis());

  @Override
  public void onStart() {
    //...
    chronometer.setBase(base.get());
  }

}

如果您想在 Activity/Fragment 打開時更改此基准時間,則可以通過多種方式進行。 您可以額外發送帶有基本時間的意圖、使用接口、事件總線、監控數據庫等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM