安卓 |在 LogCat 中打印活动任务堆栈

Posted

技术标签:

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

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

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

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

更新:

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

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

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

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

【问题讨论】:

你试过了吗?导入android.util.Log; Log.v("hi","hi"); developer.android.com/reference/android/util/Log.html 我知道如何记录,我要问的是,当我完成多个活动并想查看当前在堆栈。 你为什么要这样做? 【参考方案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 是什么意思?您是在谈论活动何时不再活动? 我刚刚用一个场景和一个我想要的示例更新了我的问题。

以上是关于安卓 |在 LogCat 中打印活动任务堆栈的主要内容,如果未能解决你的问题,请参考以下文章

安卓logcat打印行号

无法投射活动

清除 android 活动堆栈开始一个新活动

Android Activity Stack 未按文档中的说明工作 - 未显示任务堆栈中的最后一个活动

在 logcat 中打印变量值以在 android 中进行调试

尝试打开活动时出现 LogCat 致命错误