我有时会看到以下用于提交的堆栈跟踪,当用户没有查看活动时(状态保存后)可能会发生这种情况:
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1327)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1338)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
Run Code Online (Sandbox Code Playgroud)
看看Android源代码,这很有意义:
private void checkStateLoss() {
if (mStateSaved) {
throw new IllegalStateException(
"Can not perform this action after onSaveInstanceState");
}
if (mNoTransactionsBecause != null) {
throw new IllegalStateException(
"Can not perform this action inside of " + mNoTransactionsBecause);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我想知道是否有任何方法(除了在(保存/恢复)InstanceState中存储类变量)以检查片段是否将以不合需要的状态提交,这样我可以存储事务以供日后使用在适当的时候提交.
android android-fragments fragmentmanager android-savedstate onsaveinstancestate
我在Android崩溃报告中看到以下错误:
android.os.BadParcelableException: ClassNotFoundException when unmarshalling: android.support.v7.widget.Toolbar$SavedState
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2318)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2396)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3974)
at android.app.ActivityThread.access$900(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1299)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:149)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: android.support.v7.widget.Toolbar$SavedState
at android.os.Parcel.readParcelableCreator(Parcel.java:2154)
at android.os.Parcel.readParcelable(Parcel.java:2104)
at android.os.Parcel.readValue(Parcel.java:2020)
at android.os.Parcel.readSparseArrayInternal(Parcel.java:2382)
at android.os.Parcel.readSparseArray(Parcel.java:1742)
at android.os.Parcel.readValue(Parcel.java:2077)
at android.os.Parcel.readArrayMapInternal(Parcel.java:2321)
at android.os.Bundle.unparcel(Bundle.java:249)
at android.os.Bundle.getSparseParcelableArray(Bundle.java:1273)
at com.android.internal.policy.impl.PhoneWindow.restoreHierarchyState(PhoneWindow.java:1744)
at android.app.Activity.onRestoreInstanceState(Activity.java:1017)
at android.app.Activity.performRestoreInstanceState(Activity.java:989)
at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1138)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2284)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2396)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3974)
at android.app.ActivityThread.access$900(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1299)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:149)
at …
Run Code Online (Sandbox Code Playgroud) android android-appcompat android-toolbar android-savedstate
我在Android中请求权限后尝试执行片段事务 - 但应用程序不断崩溃.如何更改此代码以避免这种情况?
任何帮助表示赞赏.
在发送电子邮件之前检查许可:
private void emailShare() {
if (mayRequestContacts()) {
emailShareImpl();
}
}
Run Code Online (Sandbox Code Playgroud)
检查许可:
private boolean mayRequestContacts() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
return false;
}
Run Code Online (Sandbox Code Playgroud)
允许检查结果:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == REQUEST_READ_CONTACTS) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
emailShareImpl();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果获得批准,则启动碎片交易:
private void emailShareImpl() {
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
EmailReferDialog mEmailReferDialog = new EmailReferDialog();
mEmailReferDialog.setCancelable(true);
mEmailReferDialog.show(fragmentManager, "EMAIL_REFER_DIALOG"); …
Run Code Online (Sandbox Code Playgroud) android android-intent android-fragments android-permissions android-savedstate
有什么意义:
super.onCreate(null);
Run Code Online (Sandbox Code Playgroud)
代替
super.onCreate(savedInstanceState);
Run Code Online (Sandbox Code Playgroud)
通过这种改变,我能够避免许多问题,否则Activity
每次发生配置更改时都会困扰我(旋转,区域设置转换,权限切换).似乎通过此更改,Activity
只要配置更改触发重新启动,就会重新启动.而且我似乎没有丢失任何数据或进程状态:我Activity
的所有s都完全恢复到以前的状态.
我的问题是,我今后可以逍遥法外,或者在讨价还价中丢失一些东西吗?我真的不明白为什么这样做,无论是否安全,以及它对我的应用程序可能产生的意外影响.
我偶然发现这一招在这里.
相关问题:
android android-lifecycle android-configchanges android-activity android-savedstate
我使用的是生命周期版本 2.2.0-rc03,发现的官方文档和文章甚至没有列出正确的类名或构造函数参数。我想我必须通过这样的事情来获取 ViewModel 实例
viewModel = ViewModelProvider(this, SavedStateViewModelFactory(requireActivity().application, savedStateRegistryOwner))
.get(SelectedTracksViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚 SavedStateRegistryOwner。
有人可以举一个简单的例子来说明如何创建保存状态的 ViewModel 实例以及在 ViewModel 中保存和恢复值的正确方法吗?
我有一个活动,持有并显示多个片段.
当我重新输入片段时,它会自动填充所有editTexts中的文本.所有字段的文本也相同.
例:
打开片段并在两个editTexts中填写文本:
CustomEditText1:[______]
CustomEditText2:[_ acb__]
CustomEditText3:[_ qwe__]
单击后退按钮并重新输入片段
CustomEditText1:[_ qwe__]
CustomEditText2:[_ qwe__]
CustomEditText3:[_ qwe__]
这是我在片段中覆盖的方法:
public AddBookingFragment() {
// Required empty public constructor
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
tabsActivity = (TabsActivity) getActivity();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_add_booking, container, false);
lastNameEditText = (NASEditText) view.findViewById(R.id.nas_add_booking_last_name);
pnrEditText = (NASEditText) view.findViewById(R.id.nas_add_booking_pnr);
addButton = (NASButton) view.findViewById(R.id.nas_add_booking_add_button);
scanButton = (NASButton) view.findViewById(R.id.nas_add_booking_scan_button);
confirmationBox = (LinearLayout) view.findViewById(R.id.nas_add_booking_confirmation_box);
confirmationText = (NASHeaderAndSubtext) view.findViewById(R.id.nas_add_booking_confirmation_text);
confirmationBox.setVisibility(View.GONE);
bindButtons(); …
Run Code Online (Sandbox Code Playgroud) android android-edittext android-fragments android-activity android-savedstate
我想使用 saveStateHandle 将一些数据从活动直接传递到片段的视图模型。
在我的活动中我有:
navController.addOnDestinationChangedListener { controller, _, _ ->
controller.currentBackStackEntry?.savedStateHandle?.set(
"foo",
"bar"
)
}
Run Code Online (Sandbox Code Playgroud)
所以viewModel中的代码如下所示:
MyViewModel(state: SavedStateHandle) : ViewModel() {
init {
state
?.getStateFlow("foo", "")
?.onEach { /* do something */ }
?.launchIn(viewModelScope)
}
Run Code Online (Sandbox Code Playgroud)
由于某种原因,期望值bar
永远不会被发出。
我已经检查了Fragment本身,数据就在那里:
val handle = findNavController().currentBackStackEntry?.savedStateHandle
handle?.getLiveData<String>("foo")?.observe(viewLifecycleOwner) {
// here it is
}
Run Code Online (Sandbox Code Playgroud)
但是是否有可能将数据直接传递到 viewModel 的 savingStateHandle ?我相信应该是这样,因为导航器以某种方式通过了。
android android-savedstate android-viewmodel android-jetpack-navigation viewmodel-savedstate
我有一个自定义视图,让我们说这是它的代码:
public class CustomView extends View {
boolean visible;
boolean enabled;
public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomView, 0, 0);
try {
visible = a.getBoolean(R.styleable.CustomView_visible, true);
enabled = a.getBoolean(R.styleable.CustomView_enabled, true);
} finally {
a.recycle();
}
// Apply XML attributes here
}
@Override
public Parcelable onSaveInstanceState() {
// Save instance state
Bundle bundle = new Bundle();
bundle.putParcelable("superState", super.onSaveInstanceState());
bundle.putBoolean("visible", visible);
bundle.putBoolean("enabled", enabled);
return bundle;
}
@Override
public void …
Run Code Online (Sandbox Code Playgroud) 如/sf/answers/4281666581/所示,我们可以将LiveData保存在savedStateHandle中。
我可以轻松做到这一点 /sf/answers/4281666581/
private val textLiveData: MutableLiveData<String>
init {
textLiveData = savedStateHandle.getLiveData(KEY)
}
Run Code Online (Sandbox Code Playgroud)
但是,当尝试按如下方式保存时,
savedStateHandle.set(KEY, textLiveData)
Run Code Online (Sandbox Code Playgroud)
我收到错误
java.lang.IllegalArgumentException: Can't put value with type class androidx.lifecycle.SavedStateHandle$SavingStateLiveData into saved state
Run Code Online (Sandbox Code Playgroud)
我哪里弄错了?
android android-savedstate android-livedata android-architecture-components
我是Android的初学者.
在Android中,一些通用元素可以在onSaveInstanceState
/中自动保存/恢复onRestoreInstanceState
.
例如,EditText
保存/恢复Text
属性,RatingBar
保存/恢复Rating
属性...
我从一些测试中看到,但我在文档中找不到任何相关内容.
如果没有我的干预,我怎么能知道隐含地保存/恢复了什么?
例如,我可以找到EditText.Text
自动保存/恢复的地方?
我特别不想测试所有属性.
从JRG回复编辑:
https://developer.android.com/guide/components/activities/activity-lifecycle.html
保存活动状态当您的活动开始停止时,系统将调用onSaveInstanceState()方法<...>此方法的默认实现保存有关活动视图层次结构状态的瞬态信息,例如EditText小部件中的文本或ListView小部件的滚动位置.
我怎么知道保存/恢复的默认实现是什么?
重读JRG后的第二次编辑回答:
默认情况下,系统使用Bundle实例状态来保存有关活动布局中每个View对象的信息(例如输入到EditText小部件中的文本值).
默认实现保存/恢复元素视图的所有状态.