【问题标题】:Android | Print activity task stack/s in LogCat安卓 |在 LogCat 中打印活动任务堆栈
【发布时间】:2017-09-21 13:34:20
【问题描述】:

我想在 LogCat 上打印我的 Android 应用程序启动的所有任务以及其中的活动名称。 SDK 中是否有任何 API 可以为我提供这些信息?

附言我不能也不想使用 adb shell 命令,因为我想在 LogCat 中打印日志

注意:我已经搜索了很多,我发现的只是我无法使用的 adb shell 命令。请在回答时记住这一点。

更新:

这是我想要的 2 个场景的示例:

  1. 应用程序从活动 A 开始,我完成它并开始活动 B。然后我 按下活动 B 上的按钮,启动活动 C。现在我的默认设置 任务想C -> B 即当我按下回,我会看到活动 B 并且在按回应用程序将完成并且启动器将是 显示。
  2. 我连续打开活动 A、B 和 C,然后启动 带有意图标志Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK 的活动 X,然后打开活动 Y 和 Z。 当前任务现在看起来像 Z -> Y -> X

所以,我想在 logcat 中打印这些:

  1. C -> B 在案例 1 中
  2. Z -> Y -> X 在案例 2 中

【问题讨论】:

标签: android shell android-activity logcat


【解决方案1】:

到目前为止,使用 SDK 中的 API 开箱即用是不可能的。更多信息可以在这个链接中找到:

How to get a list of my app's tasks and the stack of their Activities?

我的解决方案:

我必须在我的应用程序的基类中添加日志记录,打印活动名称及其任务 ID 以调试我面临的问题。这是我的基本活动类的代码:

public abstract class BaseAppActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i("TESTING", "CREATED: " + getClass().getSimpleName() + " -- TASK ID: " + getTaskId());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("TESTING", "DESTROYED: " + getClass().getSimpleName() + " -- TASK ID: " + getTaskId());
    }
}

【讨论】:

    【解决方案2】:

    您可以在 Android Studio 中生成活动状态报告。它为您提供当前(正在运行)的活动的状态和活动路线。

    Android Monitor 中找到System Information 标签。

    那么,Activity Manager State

    然后,它将生成您的活动堆栈。查找 ACTIVITY(全部大写)。

    希望它有所帮助,尽管它不是日志方法。

    【讨论】:

    • 是的,这是 AS 提供的很棒的东西。我只想要日志解决方案,否则这个和 shell dumpsys 解决方案是最好的。无论如何,谢谢!
    • 此功能 is gone 来自 AS 3 :(
    【解决方案3】:

    随着时间的推移,有些人可能已经转向(Kotlin 和)“具有多个片段的单个活动”模式。我们可以记录哪个 backstack:

    fun FragmentManager.printBackStack() {
            Log.d("TAG", "BackStackEntryCount = $backStackEntryCount")
            for (i in 0 until backStackEntryCount) {
                Log.d("TAG", "    #$i is ${getBackStackEntryAt(i)}")
            }
    }
    

    从一个活动中调用它看起来像:

    supportFragmentManager.printPackStack()
    

    请记住,片段事务是异步工作的。 因此,下面的代码会产生意想不到的结果:

    addSomeFragmentToBackStack("MyFragmentTag")
    printBackStack()
    // result doesn't include "MyFragmentTag"
    

    相反,您需要延迟执行打印:

    addSomeFragmentToBackStack("MyFragmentTag")
    Handler().postDelayed(
        { printBackStack() },
        500 // ms delay
    )
    

    这个解决方案绝对不是完美的,但它可以用于调试(例如,由于Handler,在循环中调用时会产生意想不到的结果)

    【讨论】:

      【解决方案4】:

      您似乎对记录应用程序的生命周期感兴趣(对于组件 Activity、Fragments、App、Service、BroadcastReciever 等)。您可以通过制作一个超类并扩展它来打印它的生命周期方法中的Log,这样您就不需要每次都打印它。您需要制作一个super-Activity,super-Fragment等

      例如以下将记录每次应用程序由操作系统初始化(通过启动器,通过广播接收器)

         public class LifeCycleApp extends Application {
      
              String TAG = "GUFRAN " + LifeCycleApp.class.getName();
      
              public LifeCycleApp() {
                Log.d(TAG, "LifeCycleApp: constructor");
              }
      
              @Override
              public void onCreate() {
                super.onCreate();
                Log.d(TAG, "onCreate: ");
              }
      
              // Called by the system when the device configuration changes while your component is running.
              // Overriding this method is totally optional!
              @Override
              public void onConfigurationChanged(Configuration newConfig) {
                super.onConfigurationChanged(newConfig);
              }
      
              // This is called when the overall system is running low on memory,
              // and would like actively running processes to tighten their belts.
              // Overriding this method is totally optional!
              //Called when the overall system is running low on memory, and actively running processes should trim their memory usage
              @Override
              public void onLowMemory() {
                super.onLowMemory();
              }
      
              @Override
              protected void finalize() throws Throwable {
                super.finalize();
                Log.d(TAG, "finalize: ");
              }
          }
      

      你可能想看看这个 https://github.com/guffyWave/LifeCycle

      【讨论】:

      • 这实际上不是我想要的。我刚刚用一个场景和一个我想要的例子更新了我的问题。
      【解决方案5】:

      根据Android Developers

      一般情况下,您应该使用 Log.v()、Log.d()、Log.i()、Log.w() 和 Log.e() 方法来写入日志。然后就可以在 logcat 中查看日志了。

      import android.util.Log;
      public class MyActivity extends Activity{
          private static final String TAG = "MyActivity";
          @Override
          public void onCreate(Bundle bundle){
              Log.v(TAG, "on create");
          }
      }
      

      更新

      因为您想跟踪活动活动并且您知道活动周期是如何工作的。解决方案是这样的:

      @Override
      public void onPause(Bundle bundle){
          Log.v(TAG,"  activity A paused"); // or whatever 
      }
      

      其他解决方案是在startActivity 之前执行此操作 像这样:

      Intent i = new Intent(ThisActivity.class,AnotherActivity.class);
      Log.v(TAG,"A->b");
      // Log.v(TAG,"Z -> Y -> X"); or what ever message you want to print
      startActivity(i);
      

      如果您不确定哪个活动将启动哪个意图,第三种解决方案是提供一些信息。

      在活动 A 中,在开始意图之前执行此操作:

      intent.putExtra("UActivity", "From A");
      

      在活动 B 中在 onCreate 中执行此操作:

      String from = getIntent().getStringExtra("UActivity");
      if("From A".equals(from){
          Log.v(TAG,"A->B");
      }else if("From C".equals(from){
          Log.v(TAG,"C->B");
      }// etc else if
      

      所以只需跟进活动lifecycle 并以正确的方法打印正确的日志消息,这应该可以正常工作。

      【讨论】:

      • 我知道如何记录,我要问的是,当我完成多个活动并想查看当前在堆栈。
      • activity stack/s 是什么意思?您是在谈论活动何时不再活动?
      • 我刚刚用一个场景和一个我想要的示例更新了我的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-23
      相关资源
      最近更新 更多