Subclasses:
CarAppActivity, LauncherActivity, BaseCarAppActivity, AppSearchDebugActivity, SlicePermissionActivity, FragmentScenario.EmptyFragmentActivity, DeviceCredentialHandlerActivity, AppCompatActivity
Gradle dependencies
compile group: 'androidx.fragment', name: 'fragment', version: '1.8.3'
- groupId: androidx.fragment
- artifactId: fragment
- version: 1.8.3
Artifact androidx.fragment:fragment:1.8.3 it located at Google repository (https://maven.google.com/)
Androidx artifact mapping:
androidx.fragment:fragment com.android.support:support-fragment
Androidx class mapping:
androidx.fragment.app.FragmentActivity android.support.v4.app.FragmentActivity
Overview
Base class for activities that want to use the support-based
Fragments.
Known limitations:
Summary
Constructors |
---|
public | FragmentActivity()
Default constructor for FragmentActivity. |
public | FragmentActivity(int contentLayoutId)
Alternate constructor that can be used to provide a default layout
that will be inflated as part of super.onCreate(savedInstanceState) . |
Methods |
---|
public void | dump(java.lang.String prefix, java.io.FileDescriptor fd, java.io.PrintWriter writer, java.lang.String args[])
Print the Activity's state into the given stream. |
public FragmentManager | getSupportFragmentManager()
Return the FragmentManager for interacting with fragments associated
with this activity. |
public LoaderManager | getSupportLoaderManager()
|
protected void | onActivityResult(int requestCode, int resultCode, Intent data)
|
public void | onAttachFragment(Fragment fragment)
Called when a fragment is attached to the activity. |
protected void | onCreate(Bundle savedInstanceState)
Perform initialization of all fragments. |
public View | onCreateView(java.lang.String name, Context context, AttributeSet attrs)
|
public View | onCreateView(View parent, java.lang.String name, Context context, AttributeSet attrs)
|
protected void | onDestroy()
Destroy all fragments. |
public boolean | onMenuItemSelected(int featureId, MenuItem item)
|
protected void | onPause()
Dispatch onPause() to fragments. |
protected void | onPostResume()
Dispatch onResume() to fragments. |
public void | onRequestPermissionsResult(int requestCode, java.lang.String permissions[], int[] grantResults[])
|
protected void | onResume()
Dispatch onResume() to fragments. |
protected void | onResumeFragments()
This is the fragment-orientated version of FragmentActivity.onResume() that you
can override to perform operations in the Activity at the same point
where its fragments are resumed. |
protected void | onStart()
Dispatch onStart() to all fragments. |
public void | onStateNotSaved()
Hook in to note that fragment state is no longer saved. |
protected void | onStop()
Dispatch onStop() to all fragments. |
public void | setEnterSharedElementCallback(SharedElementCallback callback)
When was used to start an Activity, callback
will be called to handle shared elements on the launched Activity. |
public void | setExitSharedElementCallback(SharedElementCallback listener)
When was used to start an Activity, listener
will be called to handle shared elements on the launching Activity. |
public void | startActivityFromFragment(Fragment fragment, Intent intent, int requestCode)
Called by Fragment.startActivityForResult() to implement its behavior. |
public void | startActivityFromFragment(Fragment fragment, Intent intent, int requestCode, Bundle options)
Called by Fragment.startActivityForResult() to implement its behavior. |
public void | startIntentSenderFromFragment(Fragment fragment, IntentSender intent, int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options)
Called by Fragment.startIntentSenderForResult() to implement its behavior. |
public void | supportFinishAfterTransition()
Reverses the Activity Scene entry Transition and triggers the calling Activity
to reverse its exit Transition. |
public void | supportInvalidateOptionsMenu()
Support library version of . |
public void | supportPostponeEnterTransition()
Support library version of that works
only on API 21 and later. |
public void | supportStartPostponedEnterTransition()
Support library version of
that only works with API 21 and later. |
public final void | validateRequestPermissionsRequestCode(int requestCode)
|
from ComponentActivity | addContentView, addMenuProvider, addMenuProvider, addMenuProvider, addOnConfigurationChangedListener, addOnContextAvailableListener, addOnMultiWindowModeChangedListener, addOnNewIntentListener, addOnPictureInPictureModeChangedListener, addOnTrimMemoryListener, getActivityResultRegistry, getDefaultViewModelCreationExtras, getDefaultViewModelProviderFactory, getLastCustomNonConfigurationInstance, getLifecycle, getOnBackPressedDispatcher, getSavedStateRegistry, getViewModelStore, invalidateMenu, onBackPressed, onConfigurationChanged, onCreateOptionsMenu, onMultiWindowModeChanged, onMultiWindowModeChanged, onNewIntent, onOptionsItemSelected, onPanelClosed, onPictureInPictureModeChanged, onPictureInPictureModeChanged, onPrepareOptionsMenu, onRetainCustomNonConfigurationInstance, onRetainNonConfigurationInstance, onSaveInstanceState, onTrimMemory, peekAvailableContext, registerForActivityResult, registerForActivityResult, removeMenuProvider, removeOnConfigurationChangedListener, removeOnContextAvailableListener, removeOnMultiWindowModeChangedListener, removeOnNewIntentListener, removeOnPictureInPictureModeChangedListener, removeOnTrimMemoryListener, reportFullyDrawn, setContentView, setContentView, setContentView, startActivityForResult, startActivityForResult, startIntentSenderForResult, startIntentSenderForResult |
from ComponentActivity | dispatchKeyEvent, dispatchKeyShortcutEvent, getExtraData, putExtraData, shouldDumpInternalState, superDispatchKeyEvent |
from java.lang.Object | clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructors
public
FragmentActivity()
Default constructor for FragmentActivity. All Activities must have a default constructor
for API 27 and lower devices or when using the default
.
public
FragmentActivity(int contentLayoutId)
Alternate constructor that can be used to provide a default layout
that will be inflated as part of super.onCreate(savedInstanceState)
.
This should generally be called from your constructor that takes no parameters,
as is required for API 27 and lower or when using the default
.
See also: FragmentActivity.FragmentActivity()
Methods
protected void
onActivityResult(int requestCode, int resultCode, Intent data)
Deprecated: This method has been deprecated in favor of using the Activity Result API
which brings increased type safety via an ActivityResultContract and the prebuilt
contracts for common intents available in
ActivityResultContracts, provides hooks for
testing, and allow receiving results in separate, testable classes independent from your
activity. Use
ComponentActivity.registerForActivityResult(ActivityResultContract, ActivityResultCallback)
with the appropriate ActivityResultContract and handling the result in the
callback.
public void
supportFinishAfterTransition()
Reverses the Activity Scene entry Transition and triggers the calling Activity
to reverse its exit Transition. When the exit Transition completes,
FragmentActivity is called. If no entry Transition was used, finish() is called
immediately and the Activity exit Transition is run.
On Android 4.4 or lower, this method only finishes the Activity with no
special exit transition.
When was used to start an Activity, callback
will be called to handle shared elements on the launched Activity. This requires
Window
.
Parameters:
callback: Used to manipulate shared element transitions on the launched Activity.
When was used to start an Activity, listener
will be called to handle shared elements on the launching Activity. Most
calls will only come when returning from the started Activity.
This requires Window
.
Parameters:
listener: Used to manipulate shared element transitions on the launching Activity.
public void
supportPostponeEnterTransition()
Support library version of that works
only on API 21 and later.
public void
supportStartPostponedEnterTransition()
Support library version of
that only works with API 21 and later.
protected void
onCreate(Bundle savedInstanceState)
Perform initialization of all fragments.
public View
onCreateView(View parent, java.lang.String name, Context context, AttributeSet attrs)
public View
onCreateView(java.lang.String name, Context context, AttributeSet attrs)
protected void
onDestroy()
Destroy all fragments.
public boolean
onMenuItemSelected(int featureId, MenuItem item)
Dispatch onPause() to fragments.
public void
onStateNotSaved()
Hook in to note that fragment state is no longer saved.
protected void
onResume()
Dispatch onResume() to fragments. Note that for better inter-operation
with older versions of the platform, at the point of this call the
fragments attached to the activity are not resumed.
protected void
onPostResume()
Dispatch onResume() to fragments.
protected void
onResumeFragments()
This is the fragment-orientated version of FragmentActivity.onResume() that you
can override to perform operations in the Activity at the same point
where its fragments are resumed. Be sure to always call through to
the super-class.
Dispatch onStart() to all fragments.
Dispatch onStop() to all fragments.
public void
supportInvalidateOptionsMenu()
Deprecated: Call directly.
Support library version of .
Invalidate the activity's options menu. This will cause relevant presentations
of the menu to fully update via calls to onCreateOptionsMenu and
onPrepareOptionsMenu the next time the menu is requested.
public void
dump(java.lang.String prefix, java.io.FileDescriptor fd, java.io.PrintWriter writer, java.lang.String args[])
Print the Activity's state into the given stream. This gets invoked if
you run "adb shell dumpsys activity ".
Parameters:
prefix: Desired prefix to prepend at each line of output.
fd: The raw file descriptor that the dump is being sent to.
writer: The PrintWriter to which you should dump your state. This will be
closed for you after you return.
args: additional arguments to the dump request.
public void
onAttachFragment(
Fragment fragment)
Deprecated: The responsibility for listening for fragments being attached has been moved
to FragmentManager. You can add a listener to
this Activity's FragmentManager by calling
FragmentManager.addFragmentOnAttachListener(FragmentOnAttachListener)
in your constructor to get callbacks when a fragment is attached directly to
the activity's FragmentManager.
Called when a fragment is attached to the activity.
This is called after the attached fragment's onAttach
and before
the attached fragment's onCreate
if the fragment has not yet had a previous
call to onCreate
.
Return the FragmentManager for interacting with fragments associated
with this activity.
Deprecated: Use
LoaderManager.getInstance(this).
public final void
validateRequestPermissionsRequestCode(int requestCode)
Deprecated: there are no longer any restrictions on permissions requestCodes.
public void
onRequestPermissionsResult(int requestCode, java.lang.String permissions[], int[] grantResults[])
Deprecated: This method has been deprecated in favor of using the Activity Result API
which brings increased type safety via an ActivityResultContract and the prebuilt
contracts for common intents available in
ActivityResultContracts, provides hooks for
testing, and allow receiving results in separate, testable classes independent from your
activity. Use
ComponentActivity.registerForActivityResult(ActivityResultContract, ActivityResultCallback) passing
in a ActivityResultContracts.RequestMultiplePermissions object for the ActivityResultContract and
handling the result in the callback.
public void
startActivityFromFragment(
Fragment fragment, Intent intent, int requestCode)
Called by Fragment.startActivityForResult() to implement its behavior.
Parameters:
fragment: the Fragment to start the activity from.
intent: The intent to start.
requestCode: The request code to be returned in
Fragment.onActivityResult(int, int, Intent) when the activity exits. Must be
between 0 and 65535 to be considered valid. If given requestCode is
greater than 65535, an IllegalArgumentException would be thrown.
public void
startActivityFromFragment(
Fragment fragment, Intent intent, int requestCode, Bundle options)
Called by Fragment.startActivityForResult() to implement its behavior.
Parameters:
fragment: the Fragment to start the activity from.
intent: The intent to start.
requestCode: The request code to be returned in
Fragment.onActivityResult(int, int, Intent) when the activity exits. Must be
between 0 and 65535 to be considered valid. If given requestCode is
greater than 65535, an IllegalArgumentException would be thrown.
options: Additional options for how the Activity should be started. See
for more details. This value may be null.
public void
startIntentSenderFromFragment(
Fragment fragment, IntentSender intent, int requestCode, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options)
Deprecated: Fragments should use
Fragment.registerForActivityResult(ActivityResultContract, ActivityResultCallback)
with the ActivityResultContracts.StartIntentSenderForResult contract. This method will still be called when
Fragments call the deprecated startIntentSenderForResult()
method.
Called by Fragment.startIntentSenderForResult() to implement its behavior.
Parameters:
fragment: the Fragment to start the intent sender from.
intent: The IntentSender to launch.
requestCode: The request code to be returned in
Fragment.onActivityResult(int, int, Intent) when the activity exits. Must be
between 0 and 65535 to be considered valid. If given requestCode is
greater than 65535, an IllegalArgumentException would be thrown.
fillInIntent: If non-null, this will be provided as the intent parameter to
IntentSender
.
This value may be null.
flagsMask: Intent flags in the original IntentSender that you would like to change.
flagsValues: Desired values for any bits set in flagsMask
.
extraFlags: Always set to 0.
options: Additional options for how the Activity should be started. See
for more details. This value may be null.
Source
/*
* Copyright 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.fragment.app;
import static androidx.activity.result.contract.ActivityResultContracts.StartIntentSenderForResult;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import androidx.activity.ComponentActivity;
import androidx.activity.OnBackPressedDispatcher;
import androidx.activity.OnBackPressedDispatcherOwner;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultRegistry;
import androidx.activity.result.ActivityResultRegistryOwner;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.CallSuper;
import androidx.annotation.ContentView;
import androidx.annotation.LayoutRes;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.app.MultiWindowModeChangedInfo;
import androidx.core.app.OnMultiWindowModeChangedProvider;
import androidx.core.app.OnPictureInPictureModeChangedProvider;
import androidx.core.app.PictureInPictureModeChangedInfo;
import androidx.core.app.SharedElementCallback;
import androidx.core.content.OnConfigurationChangedProvider;
import androidx.core.content.OnTrimMemoryProvider;
import androidx.core.util.Consumer;
import androidx.core.view.MenuHost;
import androidx.core.view.MenuProvider;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;
import androidx.lifecycle.ViewModelStore;
import androidx.lifecycle.ViewModelStoreOwner;
import androidx.loader.app.LoaderManager;
import androidx.savedstate.SavedStateRegistry;
import androidx.savedstate.SavedStateRegistryOwner;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Collection;
/**
* Base class for activities that want to use the support-based
* {@link Fragment Fragments}.
*
* <p>Known limitations:</p>
* <ul>
* <li> <p>When using the <code><fragment></code> tag, this implementation can not
* use the parent view's ID as the new fragment's ID. You must explicitly
* specify an ID (or tag) in the <code><fragment></code>.</p>
* </ul>
*/
public class FragmentActivity extends ComponentActivity implements
ActivityCompat.OnRequestPermissionsResultCallback,
ActivityCompat.RequestPermissionsRequestCodeValidator {
static final String LIFECYCLE_TAG = "android:support:lifecycle";
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
/**
* A {@link Lifecycle} that is exactly nested outside of when the FragmentController
* has its state changed, providing the proper nesting of Lifecycle callbacks
* <p>
* TODO(b/127528777) Drive Fragment Lifecycle with LifecycleObserver
*/
final LifecycleRegistry mFragmentLifecycleRegistry = new LifecycleRegistry(this);
boolean mCreated;
boolean mResumed;
boolean mStopped = true;
/**
* Default constructor for FragmentActivity. All Activities must have a default constructor
* for API 27 and lower devices or when using the default
* {@link android.app.AppComponentFactory}.
*/
public FragmentActivity() {
super();
init();
}
/**
* Alternate constructor that can be used to provide a default layout
* that will be inflated as part of <code>super.onCreate(savedInstanceState)</code>.
*
* <p>This should generally be called from your constructor that takes no parameters,
* as is required for API 27 and lower or when using the default
* {@link android.app.AppComponentFactory}.
*
* @see #FragmentActivity()
*/
@ContentView
public FragmentActivity(@LayoutRes int contentLayoutId) {
super(contentLayoutId);
init();
}
private void init() {
getSavedStateRegistry().registerSavedStateProvider(LIFECYCLE_TAG, () -> {
markFragmentsCreated();
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
return new Bundle();
});
// Ensure that the first OnConfigurationChangedListener
// marks the FragmentManager's state as not saved
addOnConfigurationChangedListener(newConfig -> mFragments.noteStateNotSaved());
// Ensure that the first OnNewIntentListener
// marks the FragmentManager's state as not saved
addOnNewIntentListener(newConfig -> mFragments.noteStateNotSaved());
addOnContextAvailableListener(context -> mFragments.attachHost(null /*parent*/));
}
// ------------------------------------------------------------------------
// HOOKS INTO ACTIVITY
// ------------------------------------------------------------------------
@SuppressWarnings("deprecation")
@Override
@CallSuper
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
mFragments.noteStateNotSaved();
super.onActivityResult(requestCode, resultCode, data);
}
/**
* Reverses the Activity Scene entry Transition and triggers the calling Activity
* to reverse its exit Transition. When the exit Transition completes,
* {@link #finish()} is called. If no entry Transition was used, finish() is called
* immediately and the Activity exit Transition is run.
*
* <p>On Android 4.4 or lower, this method only finishes the Activity with no
* special exit transition.</p>
*/
public void supportFinishAfterTransition() {
ActivityCompat.finishAfterTransition(this);
}
/**
* When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
* android.view.View, String)} was used to start an Activity, <var>callback</var>
* will be called to handle shared elements on the <i>launched</i> Activity. This requires
* {@link Window#FEATURE_CONTENT_TRANSITIONS}.
*
* @param callback Used to manipulate shared element transitions on the launched Activity.
*/
public void setEnterSharedElementCallback(@Nullable SharedElementCallback callback) {
ActivityCompat.setEnterSharedElementCallback(this, callback);
}
/**
* When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
* android.view.View, String)} was used to start an Activity, <var>listener</var>
* will be called to handle shared elements on the <i>launching</i> Activity. Most
* calls will only come when returning from the started Activity.
* This requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
*
* @param listener Used to manipulate shared element transitions on the launching Activity.
*/
public void setExitSharedElementCallback(@Nullable SharedElementCallback listener) {
ActivityCompat.setExitSharedElementCallback(this, listener);
}
/**
* Support library version of {@link android.app.Activity#postponeEnterTransition()} that works
* only on API 21 and later.
*/
public void supportPostponeEnterTransition() {
ActivityCompat.postponeEnterTransition(this);
}
/**
* Support library version of {@link android.app.Activity#startPostponedEnterTransition()}
* that only works with API 21 and later.
*/
public void supportStartPostponedEnterTransition() {
ActivityCompat.startPostponedEnterTransition(this);
}
/**
* {@inheritDoc}
*
* Perform initialization of all fragments.
*/
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
mFragments.dispatchCreate();
}
@Override
@Nullable
public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context,
@NonNull AttributeSet attrs) {
final View v = dispatchFragmentsOnCreateView(parent, name, context, attrs);
if (v == null) {
return super.onCreateView(parent, name, context, attrs);
}
return v;
}
@Override
@Nullable
public View onCreateView(@NonNull String name, @NonNull Context context,
@NonNull AttributeSet attrs) {
final View v = dispatchFragmentsOnCreateView(null, name, context, attrs);
if (v == null) {
return super.onCreateView(name, context, attrs);
}
return v;
}
@Nullable
final View dispatchFragmentsOnCreateView(@Nullable View parent, @NonNull String name,
@NonNull Context context, @NonNull AttributeSet attrs) {
return mFragments.onCreateView(parent, name, context, attrs);
}
/**
* {@inheritDoc}
*
* Destroy all fragments.
*/
@Override
protected void onDestroy() {
super.onDestroy();
mFragments.dispatchDestroy();
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
@Override
public boolean onMenuItemSelected(int featureId, @NonNull MenuItem item) {
if (super.onMenuItemSelected(featureId, item)) {
return true;
}
if (featureId == Window.FEATURE_CONTEXT_MENU) {
return mFragments.dispatchContextItemSelected(item);
}
return false;
}
/**
* {@inheritDoc}
*
* Dispatch onPause() to fragments.
*/
@Override
protected void onPause() {
super.onPause();
mResumed = false;
mFragments.dispatchPause();
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
}
/**
* {@inheritDoc}
*
* Hook in to note that fragment state is no longer saved.
*/
@SuppressWarnings("deprecation")
@Override
public void onStateNotSaved() {
mFragments.noteStateNotSaved();
}
/**
* {@inheritDoc}
*
* Dispatch onResume() to fragments. Note that for better inter-operation
* with older versions of the platform, at the point of this call the
* fragments attached to the activity are <em>not</em> resumed.
*/
@Override
protected void onResume() {
mFragments.noteStateNotSaved();
super.onResume();
mResumed = true;
mFragments.execPendingActions();
}
/**
* {@inheritDoc}
*
* Dispatch onResume() to fragments.
*/
@Override
protected void onPostResume() {
super.onPostResume();
onResumeFragments();
}
/**
* This is the fragment-orientated version of {@link #onResume()} that you
* can override to perform operations in the Activity at the same point
* where its fragments are resumed. Be sure to always call through to
* the super-class.
*/
protected void onResumeFragments() {
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
mFragments.dispatchResume();
}
/**
* {@inheritDoc}
*
* Dispatch onStart() to all fragments.
*/
@Override
protected void onStart() {
mFragments.noteStateNotSaved();
super.onStart();
mStopped = false;
if (!mCreated) {
mCreated = true;
mFragments.dispatchActivityCreated();
}
mFragments.execPendingActions();
// NOTE: HC onStart goes here.
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
mFragments.dispatchStart();
}
/**
* {@inheritDoc}
*
* Dispatch onStop() to all fragments.
*/
@Override
protected void onStop() {
super.onStop();
mStopped = true;
markFragmentsCreated();
mFragments.dispatchStop();
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
}
// ------------------------------------------------------------------------
// NEW METHODS
// ------------------------------------------------------------------------
/**
* Support library version of {@link Activity#invalidateOptionsMenu}.
*
* <p>Invalidate the activity's options menu. This will cause relevant presentations
* of the menu to fully update via calls to onCreateOptionsMenu and
* onPrepareOptionsMenu the next time the menu is requested.
*
* @deprecated Call {@link Activity#invalidateOptionsMenu} directly.
*/
@SuppressWarnings("DeprecatedIsStillUsed")
@Deprecated
public void supportInvalidateOptionsMenu() {
invalidateMenu();
}
/**
* Print the Activity's state into the given stream. This gets invoked if
* you run "adb shell dumpsys activity <activity_component_name>".
*
* @param prefix Desired prefix to prepend at each line of output.
* @param fd The raw file descriptor that the dump is being sent to.
* @param writer The PrintWriter to which you should dump your state. This will be
* closed for you after you return.
* @param args additional arguments to the dump request.
*/
@SuppressWarnings("deprecation")
@Override
public void dump(@NonNull String prefix, @Nullable FileDescriptor fd,
@NonNull PrintWriter writer, @Nullable String[] args) {
super.dump(prefix, fd, writer, args);
if (!shouldDumpInternalState(args)) {
return;
}
writer.print(prefix); writer.print("Local FragmentActivity ");
writer.print(Integer.toHexString(System.identityHashCode(this)));
writer.println(" State:");
String innerPrefix = prefix + " ";
writer.print(innerPrefix); writer.print("mCreated=");
writer.print(mCreated); writer.print(" mResumed=");
writer.print(mResumed); writer.print(" mStopped=");
writer.print(mStopped);
if (getApplication() != null) {
LoaderManager.getInstance(this).dump(innerPrefix, fd, writer, args);
}
mFragments.getSupportFragmentManager().dump(prefix, fd, writer, args);
}
// ------------------------------------------------------------------------
// FRAGMENT SUPPORT
// ------------------------------------------------------------------------
/**
* Called when a fragment is attached to the activity.
*
* <p>This is called after the attached fragment's <code>onAttach</code> and before
* the attached fragment's <code>onCreate</code> if the fragment has not yet had a previous
* call to <code>onCreate</code>.</p>
*
* @deprecated The responsibility for listening for fragments being attached has been moved
* to FragmentManager. You can add a listener to
* {@link #getSupportFragmentManager() this Activity's FragmentManager} by calling
* {@link FragmentManager#addFragmentOnAttachListener(FragmentOnAttachListener)}
* in your constructor to get callbacks when a fragment is attached directly to
* the activity's FragmentManager.
*/
@SuppressWarnings({"unused", "DeprecatedIsStillUsed"})
@Deprecated
@MainThread
public void onAttachFragment(@NonNull Fragment fragment) {
}
/**
* Return the FragmentManager for interacting with fragments associated
* with this activity.
*/
@NonNull
public FragmentManager getSupportFragmentManager() {
return mFragments.getSupportFragmentManager();
}
/**
* @deprecated Use
* {@link LoaderManager#getInstance(LifecycleOwner) LoaderManager.getInstance(this)}.
*/
@Deprecated
@NonNull
public LoaderManager getSupportLoaderManager() {
return LoaderManager.getInstance(this);
}
/**
* {@inheritDoc}
*
* @deprecated there are no longer any restrictions on permissions requestCodes.
*/
@Override
@Deprecated
public final void validateRequestPermissionsRequestCode(int requestCode) { }
@SuppressWarnings("deprecation")
@CallSuper
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
mFragments.noteStateNotSaved();
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
/**
* Called by Fragment.startActivityForResult() to implement its behavior.
*
* @param fragment the Fragment to start the activity from.
* @param intent The intent to start.
* @param requestCode The request code to be returned in
* {@link Fragment#onActivityResult(int, int, Intent)} when the activity exits. Must be
* between 0 and 65535 to be considered valid. If given requestCode is
* greater than 65535, an IllegalArgumentException would be thrown.
*/
public void startActivityFromFragment(@NonNull Fragment fragment,
@NonNull Intent intent, int requestCode) {
startActivityFromFragment(fragment, intent, requestCode, null);
}
/**
* Called by Fragment.startActivityForResult() to implement its behavior.
*
* @param fragment the Fragment to start the activity from.
* @param intent The intent to start.
* @param requestCode The request code to be returned in
* {@link Fragment#onActivityResult(int, int, Intent)} when the activity exits. Must be
* between 0 and 65535 to be considered valid. If given requestCode is
* greater than 65535, an IllegalArgumentException would be thrown.
* @param options Additional options for how the Activity should be started. See
* {@link Context#startActivity(Intent, Bundle)} for more details. This value may be null.
*/
@SuppressWarnings("deprecation")
public void startActivityFromFragment(@NonNull Fragment fragment,
@NonNull Intent intent, int requestCode,
@Nullable Bundle options) {
// request code will be -1 if called from fragment.startActivity
if (requestCode == -1) {
ActivityCompat.startActivityForResult(this, intent, -1, options);
return;
}
// If for some reason this method is being called directly with a requestCode that is not
// -1, redirect it to the fragment.startActivityForResult method
fragment.startActivityForResult(intent, requestCode, options);
}
/**
* Called by Fragment.startIntentSenderForResult() to implement its behavior.
*
* @param fragment the Fragment to start the intent sender from.
* @param intent The IntentSender to launch.
* @param requestCode The request code to be returned in
* {@link Fragment#onActivityResult(int, int, Intent)} when the activity exits. Must be
* between 0 and 65535 to be considered valid. If given requestCode is
* greater than 65535, an IllegalArgumentException would be thrown.
* @param fillInIntent If non-null, this will be provided as the intent parameter to
* {@link IntentSender#sendIntent(Context, int, Intent, IntentSender.OnFinished, Handler)}.
* This value may be null.
* @param flagsMask Intent flags in the original IntentSender that you would like to change.
* @param flagsValues Desired values for any bits set in <code>flagsMask</code>.
* @param extraFlags Always set to 0.
* @param options Additional options for how the Activity should be started. See
* {@link Context#startActivity(Intent, Bundle)} for more details. This value may be null.
* @throws IntentSender.SendIntentException if the call fails to execute.
*
* @deprecated Fragments should use
* {@link Fragment#registerForActivityResult(ActivityResultContract, ActivityResultCallback)}
* with the {@link StartIntentSenderForResult} contract. This method will still be called when
* Fragments call the deprecated <code>startIntentSenderForResult()</code> method.
*/
@SuppressWarnings({"deprecation"})
@Deprecated
public void startIntentSenderFromFragment(@NonNull Fragment fragment,
@NonNull IntentSender intent, int requestCode,
@Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
@Nullable Bundle options) throws IntentSender.SendIntentException {
if (requestCode == -1) {
ActivityCompat.startIntentSenderForResult(this, intent, requestCode, fillInIntent,
flagsMask, flagsValues, extraFlags, options);
return;
}
fragment.startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask,
flagsValues, extraFlags, options);
}
class HostCallbacks extends FragmentHostCallback<FragmentActivity> implements
OnConfigurationChangedProvider,
OnTrimMemoryProvider,
OnMultiWindowModeChangedProvider,
OnPictureInPictureModeChangedProvider,
ViewModelStoreOwner,
OnBackPressedDispatcherOwner,
ActivityResultRegistryOwner,
SavedStateRegistryOwner,
FragmentOnAttachListener,
MenuHost {
public HostCallbacks() {
super(FragmentActivity.this /*fragmentActivity*/);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
// Instead of directly using the Activity's Lifecycle, we
// use a LifecycleRegistry that is nested exactly outside of
// when Fragments get their lifecycle changed
// TODO(b/127528777) Drive Fragment Lifecycle with LifecycleObserver
return mFragmentLifecycleRegistry;
}
@NonNull
@Override
public ViewModelStore getViewModelStore() {
return FragmentActivity.this.getViewModelStore();
}
@NonNull
@Override
public OnBackPressedDispatcher getOnBackPressedDispatcher() {
return FragmentActivity.this.getOnBackPressedDispatcher();
}
@Override
public void onDump(@NonNull String prefix, @Nullable FileDescriptor fd,
@NonNull PrintWriter writer, @Nullable String[] args) {
FragmentActivity.this.dump(prefix, fd, writer, args);
}
@Override
public boolean onShouldSaveFragmentState(@NonNull Fragment fragment) {
return !isFinishing();
}
@Override
@NonNull
public LayoutInflater onGetLayoutInflater() {
return FragmentActivity.this.getLayoutInflater().cloneInContext(FragmentActivity.this);
}
@Override
public FragmentActivity onGetHost() {
return FragmentActivity.this;
}
@Override
public void onSupportInvalidateOptionsMenu() {
invalidateMenu();
}
@Override
public boolean onShouldShowRequestPermissionRationale(@NonNull String permission) {
return ActivityCompat.shouldShowRequestPermissionRationale(
FragmentActivity.this, permission);
}
@Override
public boolean onHasWindowAnimations() {
return getWindow() != null;
}
@Override
public int onGetWindowAnimations() {
final Window w = getWindow();
return (w == null) ? 0 : w.getAttributes().windowAnimations;
}
@SuppressWarnings("deprecation")
@Override
public void onAttachFragment(@NonNull FragmentManager fragmentManager,
@NonNull Fragment fragment) {
FragmentActivity.this.onAttachFragment(fragment);
}
@Nullable
@Override
public View onFindViewById(int id) {
return FragmentActivity.this.findViewById(id);
}
@Override
public boolean onHasView() {
final Window w = getWindow();
return (w != null && w.peekDecorView() != null);
}
@NonNull
@Override
public ActivityResultRegistry getActivityResultRegistry() {
return FragmentActivity.this.getActivityResultRegistry();
}
@NonNull
@Override
public SavedStateRegistry getSavedStateRegistry() {
return FragmentActivity.this.getSavedStateRegistry();
}
@Override
public void addOnConfigurationChangedListener(
@NonNull Consumer<Configuration> listener
) {
FragmentActivity.this.addOnConfigurationChangedListener(listener);
}
@Override
public void removeOnConfigurationChangedListener(
@NonNull Consumer<Configuration> listener
) {
FragmentActivity.this.removeOnConfigurationChangedListener(listener);
}
@Override
public void addOnTrimMemoryListener(@NonNull Consumer<Integer> listener) {
FragmentActivity.this.addOnTrimMemoryListener(listener);
}
@Override
public void removeOnTrimMemoryListener(@NonNull Consumer<Integer> listener) {
FragmentActivity.this.removeOnTrimMemoryListener(listener);
}
@Override
public void addOnMultiWindowModeChangedListener(
@NonNull Consumer<MultiWindowModeChangedInfo> listener) {
FragmentActivity.this.addOnMultiWindowModeChangedListener(listener);
}
@Override
public void removeOnMultiWindowModeChangedListener(
@NonNull Consumer<MultiWindowModeChangedInfo> listener) {
FragmentActivity.this.removeOnMultiWindowModeChangedListener(listener);
}
@Override
public void addOnPictureInPictureModeChangedListener(
@NonNull Consumer<PictureInPictureModeChangedInfo> listener) {
FragmentActivity.this.addOnPictureInPictureModeChangedListener(listener);
}
@Override
public void removeOnPictureInPictureModeChangedListener(
@NonNull Consumer<PictureInPictureModeChangedInfo> listener) {
FragmentActivity.this.removeOnPictureInPictureModeChangedListener(listener);
}
@Override
public void addMenuProvider(@NonNull MenuProvider provider) {
FragmentActivity.this.addMenuProvider(provider);
}
@Override
public void addMenuProvider(@NonNull MenuProvider provider, @NonNull LifecycleOwner owner) {
FragmentActivity.this.addMenuProvider(provider, owner);
}
@Override
public void addMenuProvider(@NonNull MenuProvider provider, @NonNull LifecycleOwner owner,
@NonNull Lifecycle.State state) {
FragmentActivity.this.addMenuProvider(provider, owner, state);
}
@Override
public void removeMenuProvider(@NonNull MenuProvider provider) {
FragmentActivity.this.removeMenuProvider(provider);
}
@Override
public void invalidateMenu() {
FragmentActivity.this.invalidateMenu();
}
}
void markFragmentsCreated() {
boolean reiterate;
do {
reiterate = markState(getSupportFragmentManager(), Lifecycle.State.CREATED);
} while (reiterate);
}
private static boolean markState(FragmentManager manager, Lifecycle.State state) {
boolean hadNotMarked = false;
Collection<Fragment> fragments = manager.getFragments();
for (Fragment fragment : fragments) {
if (fragment == null) {
continue;
}
if (fragment.getHost() != null) {
FragmentManager childFragmentManager = fragment.getChildFragmentManager();
hadNotMarked |= markState(childFragmentManager, state);
}
if (fragment.mViewLifecycleOwner != null && fragment.mViewLifecycleOwner
.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
fragment.mViewLifecycleOwner.setCurrentState(state);
hadNotMarked = true;
}
if (fragment.mLifecycleRegistry.getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
fragment.mLifecycleRegistry.setCurrentState(state);
hadNotMarked = true;
}
}
return hadNotMarked;
}
}