티스토리 뷰
Stack Overflow에 자주 검색, 등록되는 문제들과 제가 개발 중 찾아 본 문제들 중에서 나중에도 찾아 볼 것 같은 문제들을 정리하고 있습니다.
Stack Overflow에서 가장 먼저 확인하게 되는 가장 높은 점수를 받은 Solution과 현 시점에 도움이 될 수 있는 가장 최근에 업데이트(최소 점수 확보)된 Solution을 각각 정리하였습니다.
아래 word cloud를 통해 이번 포스팅의 주요 키워드를 미리 확인하세요.
How can I save an activity state using the save instance state?
액티비티 상태 저장하기
문제 내용
I've been working on the Android SDK platform, and it is a little unclear how to save an application's state. So given this minor re-tooling of the 'Hello, Android' example:
나는 안드로이드 SDK 플랫폼에서 작업을 해왔는데, 애플리케이션 상태를 저장하는 방법이 조금 불분명하다. 따라서 'Hello, Android' 예제의 사소한 재도구화를 고려하면 다음과 같습니다.
package com.android.hello;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloAndroid extends Activity {
private TextView mTextView = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTextView = new TextView(this);
if (savedInstanceState == null) {
mTextView.setText("Welcome to HelloAndroid!");
} else {
mTextView.setText("Welcome back.");
}
setContentView(mTextView);
}
}
I thought it would be enough for the simplest case, but it always responds with the first message, no matter how I navigate away from the app.
가장 간단한 경우에 충분할 것이라고 생각했지만, 앱에서 어떻게 벗어나든 항상 첫 번째 메시지로 응답합니다.
I'm sure the solution is as simple as overriding onPause
or something like that, but I've been poking away in the documentation for 30 minutes or so and haven't found anything obvious.
나는 솔루션이 onPause 또는 이와 유사한 것을 재정의하는 것처럼 간단하다고 확신하지만 문서에서 30분 정도 파헤쳐 보았지만 분명한 것을 찾지 못했습니다.
높은 점수를 받은 Solution
You need to override onSaveInstanceState(Bundle savedInstanceState)
and write the application state values you want to change to the Bundle
parameter like this:
onSaveInstanceState(Bundle savedInstanceState)를 재정의하고 다음과 같이 변경할 애플리케이션 상태 값을 번들 매개 변수에 기록해야 합니다.
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
// Save UI state changes to the savedInstanceState.
// This bundle will be passed to onCreate if the process is
// killed and restarted.
savedInstanceState.putBoolean("MyBoolean", true);
savedInstanceState.putDouble("myDouble", 1.9);
savedInstanceState.putInt("MyInt", 1);
savedInstanceState.putString("MyString", "Welcome back to Android");
// etc.
}
The Bundle is essentially a way of storing a NVP ("Name-Value Pair") map, and it will get passed in to onCreate()
and also onRestoreInstanceState()
where you would then extract the values from activity like this:
번들은 기본적으로 NVP("이름-값 쌍") 맵을 저장하는 방법이며 onCreate() 및 onRestoreInstanceState()에 전달되어 다음과 같이 액티비티에서 값을 추출합니다.
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
double myDouble = savedInstanceState.getDouble("myDouble");
int myInt = savedInstanceState.getInt("MyInt");
String myString = savedInstanceState.getString("MyString");
}
Or from a fragment.
아니면 Fragment에서.
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
double myDouble = savedInstanceState.getDouble("myDouble");
int myInt = savedInstanceState.getInt("MyInt");
String myString = savedInstanceState.getString("MyString");
}
You would usually use this technique to store instance values for your application (selections, unsaved text, etc.).
일반적으로 이 기술을 사용하여 응용 프로그램의 인스턴스 값(선택 항목, 저장되지 않은 텍스트 등)을 저장합니다.
가장 최근 달린 Solution
using Android ViewModel & SavedStateHandle to persist the serializable data
Android View Model 및 SavedStateHandle을 사용하여 직렬화 가능한 데이터 유지
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
binding.setViewModel(new ViewModelProvider(this).get(ViewModel.class));
binding.setLifecycleOwner(this);
setContentView(binding.getRoot());
}
public static class ViewModel extends AndroidViewModel {
//This field SURVIVE the background process reclaim/killing & the configuration change
public final SavedStateHandle savedStateHandle;
//This field NOT SURVIVE the background process reclaim/killing but SURVIVE the configuration change
public final MutableLiveData<String> inputText2 = new MutableLiveData<>();
public ViewModel(@NonNull Application application, SavedStateHandle savedStateHandle) {
super(application);
this.savedStateHandle = savedStateHandle;
}
}
}
in layout file
레이아웃 파일로
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="viewModel"
type="com.xxx.viewmodelsavedstatetest.MainActivity.ViewModel" />
</data>
<LinearLayout xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autofillHints=""
android:hint="This field SURVIVE the background process reclaim/killing & the configuration change"
android:text='@={(String)viewModel.savedStateHandle.getLiveData("activity_main/inputText", "")}' />
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress='@={(Integer)viewModel.savedStateHandle.getLiveData("activity_main/progress", 50)}' />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="This field SURVIVE the background process reclaim/killing & the configuration change"
android:text='@={(String)viewModel.savedStateHandle.getLiveData("activity_main/inputText", "")}' />
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress='@={(Integer)viewModel.savedStateHandle.getLiveData("activity_main/progress", 50)}' />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="This field NOT SURVIVE the background process reclaim/killing but SURVIVE the configuration change"
android:text='@={viewModel.inputText2}' />
</LinearLayout>
</layout>
Test:
테스트:
1. start the test activity
2. press home key to go home
3. adb shell kill <the test activity process>
4. open recent app list and restart the test activity
출처 : https://stackoverflow.com/questions/151777/how-can-i-save-an-activity-state-using-the-save-instance-state
'개발 > 안드로이드' 카테고리의 다른 글
WebView에서 JavaScript 함수 호출 (0) | 2022.12.01 |
---|---|
"Unable to add window — token null is not for an application” 오류 수정하기 (0) | 2022.12.01 |
Fragment에서 Context 사용하기 (0) | 2022.11.30 |
브라우저에 특정 URL 열기 인텐트 보내기 (0) | 2022.11.30 |
Android WebView & 로컬 스토리지 (0) | 2022.11.30 |