I have an activity which contains settings. After launching SettingsActivity.java its crashing. It works well when tested in physical device i.e, API 19, API23, API26. I'm facing this issue only in API 29. What is the cause for this problem & How to fix it? refer to the code below
SettingActivity.java
package ak.wp.meto.activity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.view.MenuItem;
import android.widget.Toast;
import java.io.File;
public class SettingsActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initView();
initToolbar();
}
private void initView() {
setContentView(R.layout.activity_settings);
// replace linear layout by preference screen
getFragmentManager().beginTransaction().replace(R.id.content, new MyPreferenceFragment()).commit();
}
private void initToolbar() {
Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setTitle(getString(R.string.settings));
}
@SuppressLint("ValidFragment")
public class MyPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings_preference);
// clears web cache
final CheckBoxPreference clr_webcache = (CheckBoxPreference) getPreferenceManager().findPreference("perf_cache_clr");
clr_webcache.setChecked(false);
clr_webcache.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Toast.makeText(getApplicationContext(),"Clearing Cache, Please Wait",Toast.LENGTH_SHORT).show();
try {
trimCache(getActivity());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
});
}
private void trimCache(Context context) {
try {
File dir = context.getCacheDir();
if (dir != null && dir.isDirectory()) {
deleteDir(dir);
}
} catch (Exception e) {
// TODO: handle exception
}
}
private boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
Toast.makeText(getApplicationContext(),"FAILED:Try clearing using device settings",Toast.LENGTH_SHORT).show();
return false;
}else{
Toast.makeText(getApplicationContext(),"SUCCESS: CACHE CLEARED",Toast.LENGTH_SHORT).show();
}
}
}
// The directory is now empty so delete it
return dir.delete();
}
//END OF MYPREFERENCE FRAGMENT
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onBackPressed() {
finish();
}
}
This is my activity_settings.xml
activity_settings.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/toolbarTop"
layout="@layout/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbarTop"
android:orientation="horizontal" />
</RelativeLayout>
This is my setting_preference.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="perf_notification"
android:title="@string/pref_notification_title"
android:summary="@string/pref_notification_summ"
android:defaultValue="true" />
<ListPreference
android:key="pref_font_size"
android:title="@string/pref_text_title"
android:dialogTitle="@string/select_size"
android:entries="@array/text_entries"
android:entryValues="@array/text_entries"
android:defaultValue="@string/default_text" />
<CheckBoxPreference
android:key="perf_cache_clr"
android:title="Clear Cache"
android:summary="Deletes Cache to Load Latest Updates "
android:defaultValue="false" />
</PreferenceScreen>
Logcat says fatal exception in SettingsActivity.java in line 28 & 36 LOGCAT
2020-10-23 11:24:23.025 19845-19845/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: ak.wp.meto, PID: 19845
java.lang.RuntimeException: Unable to start activity ComponentInfo{ak.wp.meto/ak.wp.meto.activity.SettingsActivity}: java.lang.IllegalStateException: Fragment ak.wp.meto.activity.SettingsActivity.MyPreferenceFragment must be a public static class to be properly recreated from instance state.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3632)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3784)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2270)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8125)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Caused by: java.lang.IllegalStateException: Fragment ak.wp.meto.activity.SettingsActivity.MyPreferenceFragment must be a public static class to be properly recreated from instance state.
at android.app.BackStackRecord.doAddOp(BackStackRecord.java:429)
at android.app.BackStackRecord.replace(BackStackRecord.java:470)
at android.app.BackStackRecord.replace(BackStackRecord.java:462)
at ak.wp.meto.activity.SettingsActivity.initView(SettingsActivity.java:36)
at ak.wp.meto.activity.SettingsActivity.onCreate(SettingsActivity.java:28)
at android.app.Activity.performCreate(Activity.java:7957)
at android.app.Activity.performCreate(Activity.java:7946)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3607)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3784)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2270)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8125)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
I'm having ERROR in line 36
getFragmentManager().beginTransaction().replace(R.id.content, new MyPreferenceFragment()).commit();
In turn gave ERROR for function initView()
line 28
KIndly help me to sort out this issue