如果状态由我的类组成,如何在Android中更改方向时保存状态?

如果状态由我的类组成,如何在Android中更改方向时保存状态?,android,Android,我正在研究Android处理我的应用程序的方向更改的方式(我发现它会在方向更改时重新启动mainactivity。我已经看到您可以覆盖该方法 protected void onSaveInstanceState(Bundle outState) 要保存内容,请使用onStart。问题是我的视图中有自定义对象,而listview中有自定义适配器。所有内容都在这些对象的ArrayList中,但我注意到您不能将任意对象放入捆绑包中!那么如何保存状态呢?在较新版本的Android和t上编辑:兼容性库通

我正在研究Android处理我的应用程序的方向更改的方式(我发现它会在方向更改时重新启动mainactivity。我已经看到您可以覆盖该方法

protected void onSaveInstanceState(Bundle outState)

要保存内容,请使用onStart。问题是我的视图中有自定义对象,而listview中有自定义适配器。所有内容都在这些对象的ArrayList中,但我注意到您不能将任意对象放入捆绑包中!那么如何保存状态呢?

在较新版本的Android和t上编辑:兼容性库通常是处理在整个活动销毁/创建过程中重新创建数据的代价高昂的问题的最佳方法。正如Dianne指出的,保留非配置数据是为了优化缩略图生成之类的事情,出于性能原因可以很好地保存,但如果ey需要重做-它不能代替正确保存和恢复活动状态

但当我在2010年第一次回答这个问题时:

如果要保留自己的(非视图状态)数据,实际上可以使用
onretainonconfigurationinstance()传递专门用于方向更改的任意对象
。请参阅。请注意不要在传递的对象中放置任何视图或对旋转前上下文/活动的其他引用,否则将防止这些对象被垃圾收集,并可能最终耗尽内存(这称为a)。

首先,您需要确定实际的“状态”在你的应用程序中。你没有说你实际上在做什么,但让我假设对象的ArrayList是用户正在使用的状态

其次,确定此状态的实际生命周期是什么。它是否真的与该活动相关?或者如果用户说电池电量不足,设备关闭,然后他们稍后返回应用程序,用户是否应该丢失它?如果前者是,
onSaveInstanceState()
是正确的;如果是后者,则需要保存到
onPause()
中的持久存储

对于带有自定义对象的
onSaveInstanceState()
,关键是实现
Parcelable
接口。这涉及到在Parcelable上实现方法,以及在类中创建静态创建者对象。以下是典型简单Parcelable类的代码:

关键功能是可包裹实现:

和CREATOR静态类:

(静态
writeToParcel()
readFromParcel()
只是为该类提供的便利,而不是必需的。)

现在,您可以使用
Bundle将对象的整个ArrayList放入保存的状态Bundle中。putParcelableArrayList


Activity.onCreate()
中,检查是否有
savedState Bundle
,如果有,尝试从中检索ArrayList并在找到时使用它,为用于显示它的新活动创建一个新适配器和列表视图。

您是否尝试过使用:其解决方法

<activity name= ".YourActivity" android:configChanges="orientation|screenSize"/>

但是我注意到你不能把任意的对象放进包里

首先,将自定义对象设置为可包裹的

然后你可以把它们捆起来

所有内容都在这些对象的数组列表中


您可以在bundle中使用
putParcelableArrayList
方法来存储自定义“可包裹”对象的ArrayList。

使用Google的Gson将您的对象写入JSON字符串,然后将其另存为字符串。然后,在重建活动/片段时,从保存的JSON字符串中重新构建它们

import com.google.gson.Gson;

public class MyClass {
    private int a;
    private String s;
    private OtherSerializableClass other;
    private List<String> list;

    public String toJson() {
        return new Gson().toJson(this);
    }

    public static ChatAPI_MessagesArray fromJson(String json){
       return new Gson().fromJson(json, YourClass.class);
    }

    // Getters
    ...

    // Setters
    ...
}
import com.google.gson.gson;
公共类MyClass{
私人INTA;
私有字符串;
私有OtherSerializableClass other;
私人名单;
公共字符串toJson(){
返回新的Gson().toJson(this);
}
公共静态ChatAPI_MessagesArray fromJson(字符串json){
返回新的Gson().fromJson(json,YourClass.class);
}
//吸气剂
...
//二传手
...
}

对于简单数据,活动可以使用onSaveInstanceState()方法并从onCreate()中的捆绑包还原其数据,但此方法仅适用于可序列化然后反序列化的少量数据,而不适用于可能大量的数据,如用户列表或位图

The ViewModel class allows data to survive configuration changes such as screen rotations.
Architecture Components provides ViewModel helper class for the UI controller that is responsible for preparing data for the UI.

**Example**:
如果需要在应用程序中显示用户列表,请确保将获取和保留用户列表的责任分配给ViewModel,而不是活动或片段,如以下示例代码所示

public class MyViewModel extends ViewModel {
    private MutableLiveData<List<User>> users;
    public LiveData<List<User>> getUsers() {
        if (users == null) {
            users = new MutableLiveData<List<User>>();
            loadUsers();
        }
        return users;
    }

    private void loadUsers() {
        // Do an asynchronous operation to fetch users.
    }
}

public class MyActivity extends AppCompatActivity {
    public void onCreate(Bundle savedInstanceState) {
        // Create a ViewModel the first time the system calls an activity's onCreate() method.
        // Re-created activities receive the same MyViewModel instance created by the first activity.

        MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
        model.getUsers().observe(this, users -> {
            // update UI
        });
    }
}
公共类MyViewModel扩展了ViewModel{
私有可变LiveData用户;
公共LiveData getUsers(){
如果(用户==null){
用户=新的可变LiveData();
loadUsers();
}
返回用户;
}
私有void loadUsers(){
//执行异步操作以获取用户。
}
}
公共类MyActivity扩展了AppCompatActivity{
创建时的公共void(Bundle savedInstanceState){
//在系统第一次调用活动的onCreate()方法时创建ViewModel。
//重新创建的活动接收由第一个活动创建的相同MyViewModel实例。
MyViewModel model=ViewModelProviders.of(this.get)(MyViewModel.class);
model.getUsers().observe(这个,用户->{
//更新用户界面
});
}
}

请注意onRetainonConfiguration实例()应仅用于优化。即使不发生这种情况,你的应用程序也应仍然工作…因为无法保证它会工作,事实上,在许多情况下它肯定不会被调用。你应该首先通过完全保存状态机制使你的应用程序正确工作,并且只将此方法作为优化来实现。Th上面的链接不可用。你能给我一些其他的吗