I have a fragment with an inner class, something like below:
class MyFragment extends Fragment {
private DataToUiCallbacks uiCallbacks;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
uiCallbacks.onAttachData(new InnerClass);
}
void initialize(DataToUiCallbacks callbacks) {
uiCallbacks = callbacks;
}
private final class InnerClass {
// no member variables
void doSomething() {
.....
}
}
}
This fragment is called elsewhere like :
MyFragment myFragment = new MyFragment();
myFragment.initialize();
I get the following NPE :
Caused by: java.lang.NullPointerException
at com.google.android.com.google.android.myProject.MyFragment$InnerClass.<init>
at com.google.android.myProject.MyFragment.onActivityCreated
at android.app.Fragment.performActivityCreated(Fragment.java:2620)
at android.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1296)
at android.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1549)
at android.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1611)
at android.app.FragmentManagerImpl.dispatchMoveToState(FragmentManagerImpl.java:3039)
at android.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManagerImpl.java:2991)
at android.app.FragmentController.dispatchActivityCreated(FragmentController.java:178)
at android.app.Activity.performCreateCommon(Activity.java:6969)
at android.app.Activity.performCreate(Activity.java:6977)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
It's definitely happening because of the outer class being null/un-initialized while calling inner class constructor but I am calling it in onActivityCreated(), any idea what's going wrong.
For more context, the compiled code for the Inner class constructor would look like :
The compiled code for the inner constructor init :
class MyFragment$InnerClass {
final MyFragment this$0;
private MyFragment$InnerClass(MyFragment);
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:LMyFragment;
5: aload_0
6: invokespecial #2 // Method java/lang/Object."<init>":()V
9: return
}
I checked the what these mean, looks like for putfield it throws a NPE when objectRef(operand at the top of the stack) is NULL (https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.putfield) so it actually means that while assigning the implicit member variable it threw the exception.
Thanks