My Android app crashes when resuming after being killed by OS due to low memory.
So I have built the smallest possible app to reproduce the bug. My app is composed of a MainActivity, which contains 1 page in a viewPager2, which contains a fragment. This fragment is added dynamically by replacing "structure_placeholder" (in the real app, the type of fragment depends on some parameters)
MainActivity.java:
public class MainActivity extends AppCompatActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this);
ViewPager2 viewPage = findViewById(R.id.viewpager);
viewPage.setAdapter(sectionsPagerAdapter);
}
/***************************************************************************/
class SectionsPagerAdapter extends FragmentStateAdapter
{
private SectionsPagerAdapter(FragmentActivity fa)
{
super(fa);
}
@NonNull @Override
public Fragment createFragment(int position)
{
return new MyPageFragment();
}
@Override
public int getItemCount()
{
return 1;
}
}
}
activity_main.xml:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
MyPageFragment.java:
public class MyPageFragment extends Fragment
{
public MyPageFragment()
{ /* Required empty public constructor*/}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.my_page_fragment, container, false);
}
@Override
public void onStart()
{
super.onStart();
Fragment listFragment = SubFragment.newInstance();
FragmentTransaction ft = requireActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.structure_placeholder, listFragment);
ft.commit();
}
}
my_page_fragment.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".MyPageFragment">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_blank_fragment" />
<FrameLayout
android:id="@+id/structure_placeholder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
tools:layout_width="100dp"
tools:layout_height="150dp"
tools:background="@color/design_default_color_secondary"
>
</FrameLayout>
</LinearLayout>
SubFragment.java:
public class SubFragment extends Fragment
{
public SubFragment()
{ /* Required empty public constructor*/ }
public static SubFragment newInstance()
{
SubFragment fragment = new SubFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.sub_fragment, container, false);
}
}
sub_fragment.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/line1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/line2" />
</LinearLayout>
Here is the error log when resuming the app after it has been killed:
2021-11-19 15:46:55.739 8298-8298/com.delrocq.mytestapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.delrocq.mytestapp, PID: 8298
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.delrocq.mytestapp/com.delrocq.mytestapp.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f0801db (com.delrocq.mytestapp:id/structure_placeholder) for fragment SubFragment{9eb5496} (ada1c808-c885-49ed-9cd3-f4de1855c6af id=0x7f0801db)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2957)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Caused by: java.lang.IllegalArgumentException: No view found for id 0x7f0801db (com.delrocq.mytestapp:id/structure_placeholder) for fragment SubFragment{9eb5496} (ada1c808-c885-49ed-9cd3-f4de1855c6af id=0x7f0801db)
I tried to put some logs to understand the lifecycle of the activity/fragments, but it did not help.
What am I doing wrong?