I want to print all the tasks that my Android app has initiated with the names of the activities within them on LogCat. Is there any API in the SDK that can provide me this information?
ps I can't and don't want to use the adb shell commands as I want to print the logs in LogCat .
Note: I've searched quite a bit and all I've found are the adb shell commands which I can't use. Please keep that in mind while answering.
UPDATE:
Here's an example of what I want with 2 scenarios:
C -> B
ie when I press back, I'll see activity B and on pressing back app would finish and the launcher will be displayed.Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK
and then open activities Y & Z. The current task will now look like Z -> Y -> X
. So, I want to print these in logcat:
C -> B
in case 1 Z -> Y -> X
in case 2 What I am trying to do isn't possible out of the box using APIs within the SDK as of now. More info can be found in this link:
How to get a list of my app's tasks and the stack of their Activities?
My Solution:
I had to add logging in base class of my app, printing the activity's name with its task ID to debug the problem I'm facing. Here's the code of my base 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());
}
}
You can generate an activity state report in Android Studio. It gives you the states and routes of activities of the activity you are currently(running) in.
Find the System Information
tab in Android Monitor
.
Then, Activity Manager State
.
Then, it shall generate you stack of your activities. Look for ACTIVITY(all caps).
As time moves on, some folks might have moved on to (Kotlin and) a "single activity with multiple fragments" pattern. Whichs' backstack we can log:
fun FragmentManager.printBackStack() {
Log.d("TAG", "BackStackEntryCount = $backStackEntryCount")
for (i in 0 until backStackEntryCount) {
Log.d("TAG", " #$i is ${getBackStackEntryAt(i)}")
}
}
Calling this from an activity would look like:
supportFragmentManager.printPackStack()
Please keep in mind, that fragment-transactions work asynchronously. Therefore, the following code will produce unexpected results:
addSomeFragmentToBackStack("MyFragmentTag")
printBackStack()
// result doesn't include "MyFragmentTag"
Instead, you will need to execute the printing delayed:
addSomeFragmentToBackStack("MyFragmentTag")
Handler().postDelayed(
{ printBackStack() },
500 // ms delay
)
This solution definitely isn't perfect, but it's ok for debugging (eg will produce unexpected results when called in a loop due to the Handler
)
According to 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");
}
}
Since you want to track the active activities and you know how activity cycle works. The solution would be like this:
@Override
public void onPause(Bundle bundle){
Log.v(TAG," activity A paused"); // or whatever
}
Other solution would be to do this before the startActivity
something like this:
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);
Third solution would be to provide some info if you are not sure which activity will start which intent.
In activity A do this before starting the intent:
intent.putExtra("UActivity", "From A");
In activity B do this in 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
so just follow up the activity lifecycle and print the correct log messages at the correct methods and this should make it work.
It seems you are interested in logging life-cycle of your app(for components Activity,Fragments,App,Service,BroadcastReciever,etc). You can do so by making a super class and extend it to print Log in its life cycle method ,so that you need not to print it every time.You need to make a super-Activity,super-Fragment etc
For example following will log every time app is initialized by OS (by launcher, by 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: ");
}
}
You might want to look at this https://github.com/guffyWave/LifeCycle
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.