Android 如何检测导致应用程序启动的活动?

Android 如何检测导致应用程序启动的活动?,android,android-activity,Android,Android Activity,启动应用程序的活动时,运行的第一段代码是Application.onCreate()的子类。有没有办法知道是哪种活动触发了这种情况 更具体地说,在我的应用程序子类onCreate()中,我执行一些数据库初始化。这可能会失败,我的一般解决方案是启动另一个活动,在那里我可以向用户显示一些内容。如果失败发生在Application.onCreate()之外的任何地方,则此操作都可以正常工作 当失败发生在Application.onCreate()中时,Android会尝试重新启动我的应用程序子类,而我

启动应用程序的活动时,运行的第一段代码是Application.onCreate()的子类。有没有办法知道是哪种活动触发了这种情况

更具体地说,在我的应用程序子类onCreate()中,我执行一些数据库初始化。这可能会失败,我的一般解决方案是启动另一个活动,在那里我可以向用户显示一些内容。如果失败发生在Application.onCreate()之外的任何地方,则此操作都可以正常工作

当失败发生在Application.onCreate()中时,Android会尝试重新启动我的应用程序子类,而我的应用程序子类又会失败,依此类推。我可以使用activitysingleinstance属性防止无限循环。但这阻止了任何活动的启动


一种解决方案是将数据库代码移动到主活动的onStart()中。但是,如果在尝试启动错误处理活动时有办法绕过它,我更愿意将其保留在Application.onCreate()中。

如果我理解正确,您想知道是谁启动了您的活动。 如果我理解正确的话,你确实可以(至少有时)从你的应用程序内部开始这个活动

如果这两个假设都是真的,那么看看这个类。您可以使用.putString(…)和类似的方法启动一个具有意图的活动,在其中可以放入任何内容

所以,当开始你的活动时,做一些

Intent intent = new Intent(this, myotheractivity.class);
intent.putString("caller", this.getClass().getSimpleName());
startActivity(intent);
并将调用类的名称(或任何其他名称!)存储在活动中

在onCreate()或您的活动中,只需使用如下构造进行检查:

Intent intent = getIntent();
if (intent != null) {
    String caller = intent.getString("caller", "");
    if (!caller.equals("")) {
        // Here caller contains the name of the calling class
    }
}
如果此意图为null或调用者==“”,则启动此活动的不是您自己的应用程序


欢呼

一种方法是在异常处理活动中切换到,或者至少使用他们的技术

ACRA在一个单独的
:ACRA
过程中结束。然后,他们使用
ActivityManager
GetRunningAppProcess()
确定当前进程是否为
:acra
进程:

/**
 * @return true if the current process is the process running the SenderService.
 *          NB this assumes that your SenderService is configured to used the default ':acra' process.
 */
public static boolean isACRASenderServiceProcess(@NonNull Application app) {
    final String processName = getCurrentProcessName(app);
    if (ACRA.DEV_LOGGING) log.d(LOG_TAG, "ACRA processName='" + processName + "'");
    return (processName != null) && processName.equals(ACRA_PRIVATE_PROCESS_NAME);
}

@Nullable
private static String getCurrentProcessName(@NonNull Application app) {
    final int processId = android.os.Process.myPid();
    final ActivityManager manager = (ActivityManager) app.getSystemService(Context.ACTIVITY_SERVICE);
    for (final ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()){
        if(processInfo.pid == processId){
            return processInfo.processName;
        }
    }
    return null;
}
虽然在Android 5.0+中,
getRunningAppProcesses()
已被分叶,但您仍然可以将其用于自己的进程,这就是我们在这里所需要的

如果您知道自己是否处于ACRA过程中,您可以决定是否进行某些初始化,例如数据库初始化


在您的情况下,您可以将异常处理活动隔离在一个单独的命名进程中,在
应用程序#onCreate()
中查看您是否在该进程中,如果在该进程中,则跳过数据库初始化。

“我的其他活动尝试重新启动应用程序子类”-重新启动类意味着什么?我可能太简洁了。当Android启动第二个活动时,它还必须启动应用程序(如果尚未运行)。在我的例子中,这意味着在启动第二个活动时调用Application.onCreate()的子类。“当Android启动第二个活动时,它也必须启动应用程序”--只有当您将该活动指定为在其自己的进程中运行时。这通常是正确的。但由于Application.onCreate()失败,它尝试再次启动应用程序。我不知道“失败”是什么意思。如果您的意思是“未处理的异常”,请添加顶级异常处理程序。
意图
应用程序
类中不可用。对不起,您是对的。误读了发帖,他没有参加活动。我认为你答案中的关键元素是manager.getRunningAppProcesses()。有了这一点,或者类似的东西,我可能可以告诉你是什么启动了这个过程。最终,我可能会改用ACRA,但我认为这需要相当长的时间——稍后再做。@PeriHartman:“我可能知道是什么启动了这一过程”——哦,我很确定你说不出来。单独的过程表示您处于错误处理状态,应相应地继续。在当前版本的ACRA中,此代码已作为
ACRA.isacranderServiceProcess()
添加到API中。