Reputation: 19474
When launching an Activity for an app, the first piece of my code that runs is my subclass of Application.onCreate(). Is there a way to know which Activity triggered that?
More specifically, in my Application subclass onCreate(), I do some database initialization. This can fail and my general solution for failures is to launch another activity where I can display something to the user. This works fine if the failure is anywhere but in Application.onCreate().
When the failure is in Application.onCreate(), Android tries to restart my Application subclass, which in turn fails, and so on. I can prevent the infinite loop with the activity SingleInstance attribute. But that prevents any activity from starting up.
One solution would be to move my database code into my main activity's onStart(). However, I would prefer to leave it in Application.onCreate() if there's a way I can bypass it when the error handling activity is trying to launch.
Upvotes: 1
Views: 528
Reputation: 1006584
One approach would be to switch to ACRA for your exception-handling activity, or at least to use their technique.
ACRA winds up in a separate :acra
process. They then use ActivityManager
and getRunningAppProcesses()
to determine if the current process is the :acra
process or not:
/**
* @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;
}
While getRunningAppProcesses()
has been lobotomized in Android 5.0+, you can still use it for your own processes, which is all that we need here.
Given that you know whether you are in the ACRA process or not, you can decide whether or not to do certain initialization, such as your database initialization.
In your case, you would isolate the exception-handling activity in a separate named process, see if you are in that process in Application#onCreate()
, and skip the database initialization if you are.
Upvotes: 1
Reputation: 3243
If I understand you correctly, you want to know, WHO started your activity. And if I also understand correctly, you do start (at least sometimes) this activity from inside your app.
If both assumptions are true, take a look at the Intent class. You start an activity with an intent, where you can put anything in it, with methods like .putString(...) and similar.
So when starting your activity do something like
Intent intent = new Intent(this, myotheractivity.class);
intent.putString("caller", this.getClass().getSimpleName());
startActivity(intent);
And store the name of the calling class (or anything else!) in the activity.
In the onCreate() or your activity just check with a construct like this:
Intent intent = getIntent();
if (intent != null) {
String caller = intent.getString("caller", "");
if (!caller.equals("")) {
// Here caller contains the name of the calling class
}
}
If this intent is null or caller=="", it was not your own app that started this activity.
Cheers
Upvotes: 0