7

Apologies if this question sounds incredibly basic. I have an Activity that has an asynchronous network callback. The callback can execute after a user leaves the Activity.

As a check I'd like to use isFinishing() (I cannot use isDestroyed() as my min API level is 16 and not 17 which isDestroyed() requires).

Can I use isFinishing() in the callback to ensure that my logic executes only when the Activity is not destroyed?

More specifically does isFinishing() return true for an Activity that is destroyed by calling finish() even after onDestroy() is called ?

I also had a look at the source code. Here is isFinishing():

    public boolean isFinishing() {
        return mFinished;
    }

And here is finish() where the variable is set to true:

   /**
     * Finishes the current activity and specifies whether to remove the task associated with this
     * activity.
     */
    private void finish(boolean finishTask) {
        if (mParent == null) {
            int resultCode;
            Intent resultData;
            synchronized (this) {
                resultCode = mResultCode;
                resultData = mResultData;
            }
            if (false) Log.v(TAG, "Finishing self: token=" + mToken);
            try {
                if (resultData != null) {
                    resultData.prepareToLeaveProcess();
                }
                if (ActivityManagerNative.getDefault()
                        .finishActivity(mToken, resultCode, resultData, finishTask)) {
                    mFinished = true;
                }
            } catch (RemoteException e) {
                // Empty
            }
        } else {
            mParent.finishFromChild(this);
        }
    }

    /**
     * Call this when your activity is done and should be closed.  The
     * ActivityResult is propagated back to whoever launched you via
     * onActivityResult().
     */
    public void finish() {
        finish(false);
    }

I also had a look at Understanding of isFinishing() but I can't seem to derive an answer to this particular question.

Community
  • 1
  • 1
user1841702
  • 2,683
  • 6
  • 35
  • 53
  • same as the http://stackoverflow.com/questions/5227071/understanding-of-isfinishing – Nithinlal Aug 29 '16 at 11:15
  • 1
    I referenced that in the post, but I can't seem to derive an answer to my question. "More specifically does isFinishing() return true for an Activity that is destroyed by calling finish() even after onDestroy() is called ?" – user1841702 Aug 29 '16 at 11:16
  • Refer to this thread for more details about isFinishing http://stackoverflow.com/questions/5227071/understanding-of-isfinishing – Vishnu M Menon Aug 29 '16 at 11:59

2 Answers2

3

Your question is probably as good an answer as any answer could be since the javadoc of Activity.isFinishing() does not specify the return value for an already-destroyed Activity. However, judging by the source it seems that the not-at-all-confusingly-named mFinished (used by isFinishing()) is never set to false (other than on initialisation) and so once set to true will always stay that value. Having said that, mFinished is package-private so in theory another class could be modifying that value. In practice, I think it is safe to assume that isFinishing() returns true iff an Activity is finishing or has finished finishing!

In other words, isFinishing() == isFinishing() || isDestroyed()

Mark
  • 7,446
  • 5
  • 55
  • 75
0

I can confirm that I replaced (isFinishing() || isDestroyed) with isFinishing() and got a number of IllegalArgumentExceptions from Glide with the error You cannot start a load for a destroyed activity. Not perfect evidence, but enough to convince me that, at least on some platforms / devices, the two are not the same.

Tad
  • 4,668
  • 34
  • 35