Android |在 LogCat 中打印 activity 任务 stack/s

Android | Print activity task stack/s in LogCat

我想在 LogCat 上打印我的 Android 应用启动的所有任务以及其中的活动名称。 SDK中有没有API可以提供给我这个信息?

p.s。我不能也不想使用 adb shell 命令,因为我想在 LogCat.

中打印日志

注意:我搜索了很多,我发现的都是我不能使用的 adb shell 命令。回答时请记住这一点。

更新:

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

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

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

  1. C -> B 案例 1
  2. Z -> Y -> X 情况 2

根据Android Developers

Generally, you should use the Log.v(), Log.d(), Log.i(), Log.w(), and Log.e() methods to write logs. You can then view the logs in 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");
    }
}

更新

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

@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);

第三种解决方案是在您不确定哪个 activity 将启动哪个意图时提供一些信息。

在activityA开始之前做这个intent:

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

在 activity 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

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

您似乎对记录应用程序的生命周期感兴趣(对于组件 Activity、Fragments、App、Service、BroadcastReciever 等)。您可以通过创建一个 super class 并将其扩展为在其生命周期方法中打印 Log 来实现,这样您就不需要在每个 time.You 需要创建一个 super-Activity 时打印它,超级片段等

例如,每次 OS(通过启动器,通过 BroadcastReciever)初始化应用程序时都会记录以下内容

   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

到目前为止,使用 SDK 中的 API 无法开箱即用地执行我正在尝试执行的操作。可以在 link:

中找到更多信息

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

我的解决方案:

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

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());
    }
}

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

Android Monitor 中找到 System Information 选项卡。

然后,Activity Manager State.

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

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

随着时间的推移,一些人可能已经转向(Kotlin 和)“单个 activity 与多个片段”模式。我们可以记录哪些后台堆栈:

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

从 activity 调用它看起来像:

supportFragmentManager.printPackStack()

请记住,片段交易是异步进行的。 因此,下面的代码会产生意想不到的结果:

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

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

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

这个解决方案肯定不完美,但它可以用于调试(例如,由于 Handler 在循环中调用时会产生意外结果)