在 android 10 中启动时设置活动崩溃在 android 28< 中效果很好。如何解决?



我有一个包含设置的活动。启动SettingsActivity.java后崩溃。当在物理设备(即API 19、API23、API26(中测试时,它工作良好。我只在API 29中遇到这个问题。这个问题的原因是什么;如何修复?参考下面的代码

设置活动.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();
}
}

这是我的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>

这是我的settings_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在第28行的SettingsActivity.java中表示致命异常&36LOGCAT

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)

第36行出现错误

getFragmentManager().beginTransaction().replace(R.id.content, new MyPreferenceFragment()).commit();

反过来,函数initView()第28行出现错误

KIndly帮我解决这个问题

必须创建SettingsFragment的实例才能启动

public static MyPreferenceFragment getInstance() {
MyPreferenceFragment fragment = new MyPreferenceFragment();
Bundle bundle = new Bundle();
fragment.setArguments(bundle);
return fragment;
}

并通过调用进行替换

getFragmentManager().beginTransaction().replace(R.id.content, MyPreferenceFragment.getInstance()).commit();

将Fragment放入一个单独的文件中,该文件的名称与Fragment类似(MyPreferenceFragment.java(。它应该可以解决问题。

同时签出新的首选项库。Android.preference正在被弃用。代替:

import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;

用途:

import androidx.fragment.app.Fragment
import androidx.preference.CheckBoxPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat

BINGO,我解决了!!!最后,这对我起到了作用:我制作了static类的MyPreferenceFragment

public static class MyPreferenceFragment extends PreferenceFragment 

第二个问题是Toast.makeText发出ERROR,说要使MyPreferenceFragment不是静态的。所以我用代替Toast

Toast.makeText(getActivity().getApplicationContext(),"Clearing Cache, Please Wait",Toast.LENGTH_SHORT).show();

谢谢你们的支持。

相关内容

最新更新