I have read a few articles and answers (including this one) regarding deprecated code, but I'm a bit confused as to how to handle (specifically) the deprecated Fragment
event handler onInflate
.
I have replaced my implementation of
public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState)
with
public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState)
If I run my app on a < API23 machine, the replacement code is not called.
If I restore the original deprecated code (so that I now have both methods implemented) then the deprecated code is called, correct functionality returns, but a call is now being made to a deprecated method(?).
And when I run the app on an API23 machine, it appears that BOTH versions of the handler are called.
So the question is, what is happening here? If I am writing code which is supposed to run on both API23 and earlier versions, do I need to implement the deprecated methods as well as the new ones?
And if that's the case, do I need to hunt out and implement other deprecated methods "just in case"? (and, therefore, is there a list of these deprecated methods to "back-code" for?)
UPDATE :
I have now changed from using android.app.Fragment
to android.support.v4.app.Fragment
(i.e. from native fragments to support fragments) and the app is now performing as expected, with the replacement handler code running for all versions, and is stepping through the android source as expected.
But the question remains : WHY?
Why is the 'native' android.app.Fragment
implementation ****ed up? Looking back through earlier questions then this issue was being discussed back in September 2015. So why is it still an issue? And why should there be a difference in the implementation of support and native fragments post API 11?
The onAttach() callback is invoked when the fragment has been added to a FragmentManager and is attached to its host activity. At this point, the fragment is active, and the FragmentManager is managing its lifecycle state. At this point, FragmentManager methods such as findFragmentById() return this fragment.
onAttach() : Called when a Fragment is first attached to a host Activity . Use this method to check if the Activity has implemented the required listener callback for the Fragment (if a listener interface was defined in the Fragment ). After this method, onCreate() is called.
Register and create a developer profile to keep track of sessions you're interested in by saving them to My I/O.
No, you should not implement
public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState)
When a method is deprecated, you can (generally) safely use the replacement function instead. Check Fragment's definitions of onInflate:
public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState) {
mCalled = true;
final Activity hostActivity = mHost == null ? null : mHost.getActivity();
if (hostActivity != null) {
mCalled = false;
onInflate(hostActivity, attrs, savedInstanceState);
}
}
@Deprecated
public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
mCalled = true;
}
As you can see, onInflate(Context context...)
is an extension of onInflate(Activity activity...)
and is backward compatible. By calling super.onInflate(context, attrs, savedInstanceState);
inside your overridden method, you can safely assume that it will work on both API23 and earlier versions.
If I run my app on a < API23 machine, the replacement code is not called.
That seems strange, I can't reproduce it, my log is being executed with a code like this in a non-v23 machine:
@Override
public void onInflate(Context context, AttributeSet attrs,
Bundle savedInstanceState) {
super.onInflate(context, attrs, savedInstanceState);
Log.w(TAG, "I'm being executed");
}
Make sure that:
android.support.v4.app.Fragment
instead of android.app.Fragment
and that you make use of getSupportFragmentManager()
instead of getFragmentManager()
.support-v4
and appcompat-v7
as well as compileSdkVersion 23
in your build.gradle
And when I run the app on an API23 machine, it appears that BOTH versions of the handler are called.
That can be explained by the onInflate(Context context...)
code, where if it's called by an Activity, calls onInflate(Activity activity...)
EDIT
Regarding the update:
Native implementation of android.app.Fragment
isn't supposed to be backward compatible. The code of android.app.Fragment
is generally much more simpler than that of android.support.v4.app.Fragment
because of that fact.
In addition, there are some features in native implementation that cannot be introduced in support library either because it's hard by design or because it's not a priority for the developers. E.g. In native implementation, in the onInflate() source code there is some use of Transition to animate the entrance or exit of the new fragment. That is nowhere to be found in the support library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With