programing

상태가 내 클래스로 구성된 경우 Android에서 방향 변경 중 상태를 저장하는 방법은 무엇입니까?

procenter 2021. 1. 16. 10:43
반응형

상태가 내 클래스로 구성된 경우 Android에서 방향 변경 중 상태를 저장하는 방법은 무엇입니까?


Android가 내 애플리케이션의 방향 변경을 처리하는 방식을 살펴보고있었습니다 (방향 변경시 mainactivity를 다시 시작한다는 것을 발견했습니다. 메서드를 재정의 할 수 있음을 확인했습니다.

protected void onSaveInstanceState(Bundle outState)

물건을 저장하려면 onStart를 사용하세요. 문제는 사용자 지정 개체와 사용자 지정 어댑터를 사용하는 목록보기가있는 내보기가 있다는 것입니다. 모든 것이 이러한 객체의 ArrayList에 있지만 번들에 임의의 객체를 넣을 수 없다는 것을 알았습니다! 그렇다면 상태를 어떻게 저장합니까?


편집 : 최신 버전의 Android 및 호환성 라이브러리에서 유지 된 조각 은 일반적으로 활동 파괴 / 생성 전반에 걸쳐 재생성 비용이 많이 드는 데이터를 유지하는 가장 좋은 방법입니다. Dianne이 지적했듯이, 비 구성 데이터를 유지하는 것은 성능상의 이유로 저장하기에는 좋지만 다시 실행해야하는 경우 활동 기능에 중요하지 않은 썸네일 생성과 같은 것들을 최적화하기위한 것이 었습니다. 활동 상태를 적절하게 저장하고 복원하는 대신 사용할 수 없습니다.

하지만 2010 년에 처음 답변했을 때 :
자신의 (뷰 상태가 아닌) 데이터를 유지하려면 .NET을 사용하여 방향 변경을 위해 특별히 임의의 객체를 전달할 수 있습니다 onRetainNonConfigurationInstance(). 이 Android 개발자 블로그 게시물을 참조하십시오 . 그냥 당신이 전달하는 객체의 사전 회전 상황 / 활동에 대한 조회 또는 다른 참조를 넣어하지 않도록주의, 또는 쓰레기 수집되는 해당 개체를 방지 할 수 있습니다 결국 메모리가 부족할 수 있습니다 (이것은이라고 컨텍스트 누출 ).


사용해 보셨나요?

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

매니페스트 파일에서?

기본적으로 작동하지 않는 이유는 방향을 변경하면 onCreate다시 호출되고 뷰가 다시 그려지기 때문입니다.

Activity에서 처리 할 필요없이이 매개 변수를 작성하면 프레임 워크가 나머지 작업을 처리합니다. 방향이 변경되면 화면 또는 레이아웃의 상태가 유지됩니다.

참고 가로 모드에 대해 다른 레이아웃을 사용하는 경우 이러한 매개 변수를 추가하면 가로 모드에 대한 레이아웃이 호출되지 않습니다.

다른 방법다른 방법


먼저 앱에서 실제로 "상태"가 무엇인지 확인해야합니다. 실제로 무엇을하고 있는지는 말하지 않았지만 객체의 ArrayList가 사용자가 작업중인 상태라고 가정하겠습니다.

둘째,이 상태의 실제 수명주기를 결정합니다. 정말 그 활동과 관련이 있습니까? 아니면 사용자가 배터리가 부족하고 기기가 꺼졌다가 나중에 앱으로 돌아 간다고해도 잃어 버리지 않아야할까요? 전자 onSaveInstanceState()가 정확하다면; 후자의 경우 영구 저장소에 onPause().

를 들어 onSaveInstanceState()사용자 정의 객체와 키가 구현하는 Parcelable인터페이스를. 여기에는 Parcelable에서 메서드를 구현하고 클래스에서 정적 CREATOR 개체를 만드는 것이 포함됩니다. 다음은 일반적인 간단한 Parcelable 클래스에 대한 코드입니다.

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/ComponentName.java

주요 기능은 Parcelable 구현입니다.

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/ComponentName.java#317

CREATOR 정적 클래스 :

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/ComponentName.java#355

(정적 writeToParcel()이며 readFromParcel()해당 클래스에 대해 수행되었으며 필수가 아닌 편의입니다.)

이제 다음을 사용하여 객체의 전체 ArrayList를 저장된 상태 Bundle에 넣을 수 있습니다 Bundle.putParcelableArrayList.

http://developer.android.com/reference/android/os/Bundle.html#putParcelableArrayList(java.lang.String, java.util.ArrayList)

에서 Activity.onCreate()가 있는지 확인 savedState Bundle하고 만약 있다면 ArrayList를 검색하고 발견되면 사용하여 표시하는 데 사용되는 새 활동에 대한 새 어댑터 및 목록보기를 만듭니다.


하지만 번들에 임의의 개체를 넣을 수 없다는 것을 알아 차 렸습니다!

먼저 사용자 지정 개체를 Parcelable만듭니다.
그런 다음 번들에 넣을 수 있습니다.

모든 것은 이러한 객체의 ArrayList에 있습니다.

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
    ...
}

For simple data, the activity can use the onSaveInstanceState() method and restore its data from the bundle in onCreate(), but this approach is only suitable for small amounts of data that can be serialized then deserialized, not for potentially large amounts of data like a list of users or bitmaps.

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**:

if you need to display a list of users in your app, make sure to assign responsibility to acquire and keep the list of users to a ViewModel, instead of an activity or fragment, as illustrated by the following sample code.

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
        });
    }
}

ReferenceURL : https://stackoverflow.com/questions/3915952/how-to-save-state-during-orientation-change-in-android-if-the-state-is-made-of-m

반응형