开发者

WeakReference to Activity (Android)

开发者 https://www.devze.com 2023-01-15 10:29 出处:网络
In my Android app, when a user tries to trans开发者_如何学Cition from one activity to another, there may be some global state that indicates they need to complete some other action first.

In my Android app, when a user tries to trans开发者_如何学Cition from one activity to another, there may be some global state that indicates they need to complete some other action first.

To accomplish this, I've written a class with the following code:

private static WeakReference<Activity> oldActivityReference;
private static Intent waitingIntent;

public static void pushActivity(Activity currentActivity, Intent newActivityIntent) {
    Intent blockingIntent = ThisClass.getBlockingActivity();
    if (blockingIntent != null) {
        ThisClass.oldActivityReference = new WeakReference<Activity>(currentActivity);
        ThisClass.waitingIntent = newActivityIntent;
        currentActivity.startActivity(blockingIntent);
        return;
    }
    currentActivity.startActivity(newActivityIntent);
}

When the blocking activity finishes, it calls ThisClass.blockingActivityFinished(). That will check to see if the weak reference to the old activity still exists and, if so, launch the original intent from that activity. If not, it will launch the original intent from my application's context.

My question is,

Does this sound sane? Are there any potential memory leak issues with this technique? Is there a better way to accomplish this?

EDIT - To be clear, the types of events that might trigger an interruption are 1) a server ping indicating that the current app version is deprecated 2) any server RPC indicating that the user's credentials are no longer valid. I do not want to add logic to every Activity to handle checking for these, and resuming business as usual once they complete. That is a violation of DRY, and error-prone in a team environment.


Does this sound sane?

I'd never use this technique. Mutable static data members are dangerous, WeakReference notwithstanding. In particular, I'd expect this to fail if the user does the unthinkable and, say, uses their phone as a phone, or otherwise leaves your application flow for an extended period of time. Your activities may be destroyed and your process terminated to free up RAM, yet the activities would remain in the task and might be reactivated. At that point, your state is whack, because the statics got nuked.

Are there any potential memory leak issues with this technique?

You're leaking an Intent.

Is there a better way to accomplish this?

For the purposes of the rest of this answer, I'm going to refer to your starting point as Activity A, the "some other action" as Activity B, and the desired end as Activity C. So, in your code, newActivityIntent is for Activity C, blockingIntent is for Activity B, and currentActivity is Activity A.

Option #1: Put the decision-making process in Activity C, rather than Activity A. Have Activity C check the condition in onCreate() and immediately calls startActivity() for Activity B if the conditions require Activity B to be shown.

Option #2: Leave the decision-making process in Activity A, but pass the boolean (e.g., true for "we gotta show Activity B") in an Intent extra for the startActivity() call for Activity C. Activity C checks the boolean in onCreate() and immediately calls startActivity() for Activity B if the boolean says so.

In these options, you avoid the statics.

0

精彩评论

暂无评论...
验证码 换一张
取 消