29

当应用程序的进程被杀死时,它的活动堆栈被保存。然后,当应用程序重新启动时,我的所有活动都会恢复并运行到空指针中。与其修改每个活动以适应此事件,我宁愿让我的应用程序从基本活动开始,而不是尝试重新创建活动堆栈。

这可能吗?

我知道 Intent.FLAG_ACTIVITY_CLEAR_TOP,但据我所知,这只会在重新创建活动后杀死活动。

编辑:clearTaskOnLaunch是我想要的吗?我已将其添加到我的默认活动中,但没有看到任何效果。但这会杀死我的活动,即使我只是最小化应用程序,不是吗?如果整个过程正在重新启动,我宁愿只清除堆栈。

编辑 2:不,这不是我想要的 - Android 工程师对有关如何使用 ClearTaskOnLaunch 的一些问题做出了彻底的回应:http ://groups.google.com/group/android-developers/browse_thread/thread/da024bcaf4e1960f/ab1e2b35c360cb65 ?pli=1

4

5 回答 5

9

我能找到的唯一解决方案是检查 onCreate() 的每个实例中的全局静态变量,并在该变量已重置为 null 时完成,表明任务已重新启动。我将所有活动关闭到我的根活动并重新开始。

很快我希望我的应用程序可以在 onPause() 中保存所需的值,但是直到那时,这是我知道的唯一可靠的方法来处理丢失的初始化......

于 2011-04-22T17:21:05.753 回答
2

如果您正在使用 spalshScreen 或任何 LauncherActivity,您可以创建一个全局静态布尔值并像这样使用它:

首先找到一种方法来存储这个静态变量(也许创建一个全局 java 文件)

public abstract class Global {
    ...
    public static boolean processKilled = true;
    ...
}

然后,在您的 laucherActivity(MainActivity 或 Splashscreen ...)中添加以下行:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Global.processKilled = false;
        ...//your code here
    }

事实上,如果你的应用进程死了,它肯定不会通过你的launcherActivity的代码。所以静态布尔 processKilled 将保持为真。即使是这样,这也意味着您的应用程序当前正在重新启动,并且 processkiled 将被正确设置为 true 并且所有变量都会正确实例化(无 NullPointerException)

通过创建自己的 restartApp 方法,您将获得所需的内容:

(在您添加的每个活动中添加这些行:)

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (Global.processKilled){
            restartApp();
        }
        ...//your code here
    }

编辑

如果您不是全局变量狂,您可能需要检查 savedInstanceState 是否为空...

于 2020-01-18T16:12:47.160 回答
1

我使用这段代码:

public class NoRestoreActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Shoul be always NULL when created the first time, just in case...
        if (savedInstanceState != null && savedInstanceState.getInt("SavedInstance") > 0) {
            // ----- Your prefferred way to kill an application ----
            try {                
                this.finishActivity(0);               
            } catch (Exception ee) {
            }
            try {
                android.os.Process.killProcess(android.os.Process.myPid());
                System.exit(10);
            } catch (Exception eeee) {
            }
            return;
        }
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void onSaveInstanceState (Bundle outState){
        super.onSaveInstanceState(outState);
        outState.putInt("SavedInstance",1);
    }
}
于 2014-11-06T12:36:49.973 回答
1

上述依赖进程死亡来重置静态变量的解决方案是可行的,但由于它依赖于静态状态,因此会产生代码异味。这是一个具有非常相似属性的解决方案,但不依赖于进程死亡后重置的静态变量。相反,它依赖于这样一个事实,即在进程死亡后,任何保留的片段都将其实例变量设置回默认值。

/**
 * This retained fragment functions as a detector for when the activity is restoring it's state
 * after a process death.
 *
 * <p>The callback onRestoreInstanceState cannot be used here, since that callback is also invoked
 * during regular activity recreation due to configuration changes, and there's no way to tell
 * whether the state is being restored from a configuration change or from recreation after process
 * death.
 *
 * <p>This retained fragment can be used to disambiguate these two scenarios. When the fragment is
 * created, it's {@code wasProcessKilled} flag is set to {@code false}, which will be retained
 * across activity restarts from configuration changes. However, on process rebirth, the retained
 * fragment will still be retained, but the value of {@code wasProcessKilled} will be set back to
 * its default value of {@code true}.
 */
public class ProcessDeathDetectorFragment extends Fragment {

  public static final String TAG = "ProcessDeathDetectorFragmentTag";

  public static ProcessDeathDetectorFragment create() {
    ProcessDeathDetectorFragment frag = new ProcessDeathDetectorFragment();
    frag.wasProcessKilled = false;
    frag.setRetainInstance(true);
    return frag;
  }

  private boolean wasProcessKilled = true;

  public boolean wasProcessKilled() {
    return wasProcessKilled;
  }

  @VisibleForTesting
  public void clear() {
    wasProcessKilled = true;
  }
}




private void closeActivityIfRestoredAfterProcessDeath(Bundle bundle) {
  FragmentManager fragmentManager = getSupportFragmentManager();
  ProcessDeathDetectorFragment retainedFragment =
      (ProcessDeathDetectorFragment)
          fragmentManager.findFragmentByTag(ProcessDeathDetectorFragment.TAG);

  if (bundle != null && retainedFragment != null && retainedFragment.wasProcessKilled()) {
    // If the bundle is non-null, then this is a restore flow.
    // If we are in a restore flow AND the retained fragment's wasProcessKilled flag is set back
    // to its default value of true, then we are restoring
    // from process death, otherwise the flag would have the value of false that was set when it
    // was created for the first time.
    finish();
    return;
  }

  if (retainedFragment == null) {
    fragmentManager
        .beginTransaction()
        .add(ProcessDeathDetectorFragment.create(), ProcessDeathDetectorFragment.TAG)
        .commit();
  }
}

@Override
protected void onCreate(Bundle bundle) {
  super.onCreate(bundle);
  closeActivityIfRestoredAfterProcessDeath(bundle);
  ...
}
于 2019-12-20T00:32:23.163 回答
0

这是在处理原生 Android 工具时应该考虑的问题,还是第三方任务杀手提出的问题?至少在模拟器上使用“强制停止”似乎会重置活动堆栈——这是我期望在应用程序死亡时总是发生的事情。

于 2011-04-03T00:56:56.650 回答