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

时间:2017-09-21 13:34:20

标签: android shell android-activity logcat

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

P.S。我不能也不想使用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. The 当前任务现在看起来像Z -> Y -> X
  3. 所以,我想在logcat中打印这些:

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

5 个答案:

答案 0 :(得分:2)

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

System Information中找到Android Monitor标签。

enter image description here

然后,Activity Manager State

enter image description here

然后,它会生成你的活动堆栈。寻找ACTIVITY(全部上限)。

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

答案 1 :(得分:1)

到目前为止,我尝试做的事情是不可能使用SDK中的API开箱即用的。更多信息可以在以下链接中找到:

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

我的解决方案:

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

LineCollection

答案 2 :(得分:0)

根据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并使用正确的方法打印正确的日志消息,这应该可以使其正常工作。

答案 3 :(得分:0)

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

例如,以下每次应用程序初始化时都会记录操作系统(通过启动程序,通过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

答案 4 :(得分:0)

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

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,在循环中调用时会产生意想不到的结果)