[英]Automatically log Android lifecycle events using ActivityLifecycleCallbacks?
I am trying to automatically capture and log Android lifecycle events using ActivityLifecycleCallbacks, however documentation on this matter is scarce, to say the least:我正在尝试使用 ActivityLifecycleCallbacks 自动捕获和记录 Android 生命周期事件,但是至少可以说,关于此事的文档很少:
public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)
I don't want to have to extend the Activity class or override the existing lifecycle methods (onCreate, onResume, etc...) I'm looking to have a separate class listening for these events and acting accordingly.我不想扩展 Activity 类或覆盖现有的生命周期方法(onCreate、onResume 等...)我希望有一个单独的类来监听这些事件并采取相应的行动。
Does anyone have any experience in this, or have links to good solid documentation or tutorials on how this works?有没有人在这方面有任何经验,或者有关于它是如何工作的良好可靠文档或教程的链接? Specifically, how to register for ActivityLifecycleCallbacks, and how to handle them?具体来说,如何注册ActivityLifecycleCallbacks,以及如何处理?
I don't have any firsthand experience but judging from the API you can just write your own class that implements the Application.ActivityLifecycleCallbacks
interface and register that class on the provided Application
class instance我没有任何第一手经验,但从 API 来看,您可以编写自己的类来实现Application.ActivityLifecycleCallbacks
接口并在提供的Application
类实例上注册该类
getApplicaton().registerActivityLifecycleCallbacks(yourCustomClass);
This class will receive the same callbacks as your individual activities.此类将收到与您的个人活动相同的回调。 Good luck.祝你好运。
PS.附注。 This is API level 14 btw, so it won't work on older phones.顺便说一句,这是 API 级别 14,因此它不适用于旧手机。
I did my own implementation of Application.ActivityLifecycleCallbacks
.我自己实现了Application.ActivityLifecycleCallbacks
。 I'm using SherlockActivity
, but for normal Activity class might work.我正在使用SherlockActivity
,但对于普通的 Activity 类可能会起作用。
First, I'm creating an interface that have all methods for track the activities lifecycle:首先,我正在创建一个接口,其中包含用于跟踪活动生命周期的所有方法:
public interface ActivityLifecycleCallbacks{
public void onActivityStopped(Activity activity);
public void onActivityStarted(Activity activity);
public void onActivitySaveInstanceState(Activity activity, Bundle outState);
public void onActivityResumed(Activity activity);
public void onActivityPaused(Activity activity);
public void onActivityDestroyed(Activity activity);
public void onActivityCreated(Activity activity, Bundle savedInstanceState);
}
Second, I implemented this interface in my Application's class:其次,我在我的应用程序类中实现了这个接口:
public class MyApplication extends Application implements my.package.ActivityLifecycleCallbacks{
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onActivityStopped(Activity activity) {
Log.i("Tracking Activity Stopped", activity.getLocalClassName());
}
@Override
public void onActivityStarted(Activity activity) {
Log.i("Tracking Activity Started", activity.getLocalClassName());
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
Log.i("Tracking Activity SaveInstanceState", activity.getLocalClassName());
}
@Override
public void onActivityResumed(Activity activity) {
Log.i("Tracking Activity Resumed", activity.getLocalClassName());
}
@Override
public void onActivityPaused(Activity activity) {
Log.i("Tracking Activity Paused", activity.getLocalClassName());
}
@Override
public void onActivityDestroyed(Activity activity) {
Log.i("Tracking Activity Destroyed", activity.getLocalClassName());
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.i("Tracking Activity Created", activity.getLocalClassName());
}
}
Third, I'm creating a class that extends from SherlockActivity:第三,我正在创建一个从 SherlockActivity 扩展的类:
public class MySherlockActivity extends SherlockActivity {
protected MyApplication nMyApplication;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
nMyApplication = (MyApplication) getApplication();
nMyApplication.onActivityCreated(this, savedInstanceState);
}
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
nMyApplication.onActivityResumed(this);
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
nMyApplication.onActivityPaused(this);
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
nMyApplication.onActivityDestroyed(this);
}
@Override
protected void onStart() {
super.onStart();
nMyApplication.onActivityStarted(this);
}
@Override
protected void onStop() {
super.onStop();
nMyApplication.onActivityStopped(this);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
nMyApplication.onActivitySaveInstanceState(this, outState);
}
}
Fourth, all class that extend from SherlockActivity, I replaced for MySherlockActivity:第四,从 SherlockActivity 扩展的所有类,我替换为 MySherlockActivity:
public class MainActivity extends MySherlockActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Now, in the logcat you will see the logs programmed in the Interface implementation made in MyApplication.现在,在 logcat 中,您将看到在 MyApplication 中制作的接口实现中编程的日志。
UPDATE更新
This implementation was tested from API Level 9 (Gingerbread), API Level 12 (Honeycomb) and API Level 17 (Jelly Bean) and works fine.此实现已从 API 级别 9 (Gingerbread)、API 级别 12 (Honeycomb) 和 API 级别 17 (Jelly Bean) 测试,并且工作正常。 Might works in Android's older versions.可能适用于 Android 的旧版本。
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(MyApplication.this/*(Your Application Name)*/);
}
Only add this line on Application class and all works well.只在 Application 类上添加这一行,一切正常。
Try this: http://engineering.meetme.com/2015/04/android-determine-when-app-is-opened-or-closed/#comment-202试试这个: http : //engineering.meetme.com/2015/04/android-determine-when-app-is-opened-or-closed/#comment-202
It proposes an AppForegroundStateManager
to which each activity reports through its onStop()
and onStart()
functions like this:它提出了一个AppForegroundStateManager
,每个活动通过其onStop()
和onStart()
函数向其报告,如下所示:
@Override
protected void onStart() {
super.onStart();
AppForegroundStateManager.getInstance().onActivityVisible(this);
}
@Override
protected void onStop() {
AppForegroundStateManager.getInstance().onActivityNotVisible(this);
super.onStop();
}
Your Application
class implements a listener like this:您的Application
类实现了一个这样的监听器:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
AppForegroundStateManager.getInstance().addListener(this);
}
@Override
public void onAppForegroundStateChange(AppForegroundStateManager.AppForegroundState newState) {
if (AppForegroundStateManager.AppForegroundState.IN_FOREGROUND.equals(newState)) {
// App just entered the foreground. Do something here!
Log.i(TAG, "App Just Entered the Foreground with launch mechanism of: " + mLaunchMechanism);
} else {
// App just entered the background. Set our launch mode back to the default of direct.
mLaunchMechanism = LaunchMechanism.DIRECT;
}
}
}
It also includes tips and tricks for determining how the app was opened - from a notification, a URL opening your app or directly from the Apps menu.它还包括用于确定应用程序打开方式的提示和技巧 - 从通知、打开应用程序的 URL 或直接从应用程序菜单。 This is done through an Enum
in the Application class:这是通过 Application 类中的Enum
完成的:
public enum LaunchMechanism {
DIRECT,
NOTIFICATION,
URL,
BACKGROUND
}
private LaunchMechanism mLaunchMechanism = LaunchMechanism.DIRECT;
public void setLaunchMechanism(LaunchMechanism launchMechanism) {
mLaunchMechanism = launchMechanism;
}
In our implementation of this, we have flags for when we start an activity that will launch a third-party activity, like if the user makes a phone call from our app or if a browser is launched.在我们的实现中,当我们启动将启动第三方 Activity 的 Activity 时,我们有标志,例如用户是否从我们的应用程序拨打电话或启动浏览器。 In the launching activity's onStop()
we then do a check like this to only report the activity's not-visibility when those flags are false:在启动活动的onStop()
我们然后进行这样的检查,以便仅在这些标志为 false 时报告活动的不可见性:
if(!flag_userLaunchedThirdPartyActivity){
AppForegroundStateManager.getInstance().onActivityNotVisible(this);
}
For checking whether or not the application goes into the background - for example when the device's screen goes dark or the user receives a phone call - it works like this:为了检查应用程序是否进入后台 - 例如当设备的屏幕变暗或用户接到电话时 - 它的工作方式如下:
public static boolean isApplicationGoingToBackground(final Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (!topActivity.getPackageName().equals(context.getPackageName())) {
setLaunchMechanism(LaunchMechanism.BACKGROUND);
return true;
}
}
setLaunchMechanism(LaunchMechanism.DIRECT);
return false;
}
This solution is not dependent on an API level, so it should work all the way back to API level 1.此解决方案不依赖于 API 级别,因此它应该一直工作到 API 级别 1。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.