标签: android-savedstate

在提交FragmentTransaction之前检查状态是否已保存

我有时会看到以下用于提交的堆栈跟踪,当用户没有查看活动时(状态保存后)可能会发生这种情况:

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

41
推荐指数
3
解决办法
2万
查看次数

unmarshalling android.support.v7.widget.Toolbar $ SavedState时的ClassNotFoundException

我在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

19
推荐指数
1
解决办法
6141
查看次数

Android致命错误 - 在onSaveInstanceState之后无法执行此操作

我在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

14
推荐指数
1
解决办法
5003
查看次数

Android Activity实例状态

有什么意义:

super.onCreate(null);
Run Code Online (Sandbox Code Playgroud)

代替

super.onCreate(savedInstanceState);
Run Code Online (Sandbox Code Playgroud)

通过这种改变,我能够避免许多问题,否则Activity每次发生配置更改时都会困扰我(旋转,区域设置转换,权限切换).似乎通过此更改,Activity只要配置更改触发重新启动,就会重新启动.而且我似乎没有丢失任何数据或进程状态:我Activity的所有s都完全恢复到以前的状态.

我的问题是,我今后可以逍遥法外,或者在讨价还价中丢失一些东西吗?我真的不明白为什么这样做,无论是否安全,以及它对我的应用程序可能产生的意外影响.

我偶然发现这一招在这里.

相关问题:

用null参数调用super.onCreate()?

在应用程序被杀之后,'Bundle savedInstanceState'是否会存活?

活动状态实例 - 见解?

活动的实例状态:自动存储和恢复的内容

android android-lifecycle android-configchanges android-activity android-savedstate

11
推荐指数
1
解决办法
1484
查看次数

如何使用 ViewModel 的新保存状态模块

我使用的是生命周期版本 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 中保存和恢复值的正确方法吗?

android android-savedstate android-viewmodel

11
推荐指数
2
解决办法
8423
查看次数

从保存的实例恢复片段时,如何防止editText自动填充文本?

我有一个活动,持有并显示多个片段.

当我重新输入片段时,它会自动填充所有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

10
推荐指数
1
解决办法
1140
查看次数

ViewModel中的SavedStateHandle和currentBackStackEntry是否相同?

我想使用 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

10
推荐指数
0
解决办法
558
查看次数

在应用XML属性之前恢复视图状态

我有一个自定义视图,让我们说这是它的代码:

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)

android android-custom-view android-xml android-savedstate

8
推荐指数
1
解决办法
385
查看次数

如何将LiveData保存到saveStateHandle中?

如/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

8
推荐指数
2
解决办法
9504
查看次数

Android视图 - 活动中自动保存和恢复的内容

我是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小部件中的文本值).

默认实现保存/恢复元素视图的所有状态.

android activity-lifecycle android-savedstate

7
推荐指数
2
解决办法
5565
查看次数