1. OnCreate 중복호출 막기
- 해당 함수는 딱 한번만 호출되는지 알았는데 그렇지가 않았다. 키보드가 생겼다 사라진다던지, Landscape, Portrait로 변경시
중복 호출된다.
- 이를 막기 위해서는, Manifest에 다음을 추가 해야한다. 그러나 추천하지 않는다.
<activity
.....
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
......
</activity>
2. Orientation 전환등 onCreate가 호출시 기존 항목 저장, 복원
- 기본적으로 onCreate가 호출되면서 onSaveInstance() 등 시스템에서 자동으로 처리되나, 데이터가 많을경우에는
수동으로 처리해 주어야 한다.
- onSaveInstance, viewmodel을 이용한 저장방법이 있고, 아예 수동으로 저장하는 방법이 있다.
onSaveInstance의 경우에는 작은 데이터에만 유용하므로 여기선 다루지 않는다.
3. ViewModel
- UI에서 사용하는 데이터 들을 저장, 복원하는 클래스를 생성하고, 액티비티 혹은 프래그먼트에서 이 클래스를 이용한다.
- 액티비티나 프래그먼트가 소멸될때 ViewModel의 onCleared가 호출된다.
- ViewModel은 생명주기가 뷰 보다 길기 때문에, 내부에 View 를 직접 참조하면 안된다.
- 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 = new ViewModelProvider(this).get(MyViewModel.class);
model.getUsers().observe(this, users -> {
// update UI
});
}
}
3.1. 한 Activity에 속한 2개의 프래그먼트 간 데이터 공유 (ViewModel 이용)
- 한 Activity에서 2개의 프래그먼트를 사용하고, 두개가 밀접한 연관이 있을경우 ViewModel을 통해 데이터 공유가 가능하다.
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
public class ListFragment extends Fragment {
private SharedViewModel model;
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}
public class DetailFragment extends Fragment {
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
model.getSelected().observe(getViewLifecycleOwner(), item -> {
// Update the UI.
});
}
}
** UI의 데이터와 DB를 연결하는 로더를 대체할 수 있다고 하나 이는 다루지 않는다. (추후에)
참조
- https://developer.android.com/guide/topics/resources/runtime-changes?hl=ko
구성 변경 처리 | Android 개발자 | Android Developers
구성 변경 처리 일부 기기 구성은 런타임에 변경될 수 있습니다(예: 화면 방향, 키보드 가용성 및 사용자가 다중 창 모드를 활성화할 경우). 그러한 변경이 일어나는 경우 Android는 실행 중인 Activi
developer.android.com
- https://developer.android.com/topic/libraries/architecture/viewmodel?hl=ko#loaders
'Android' 카테고리의 다른 글
사용자 정의 이벤트 발생 및 수신 - otto (Broadcast) (0) | 2022.06.07 |
---|---|
기기 이벤트 수신 (windowinfotracker, consumer이용) (0) | 2022.06.07 |
Inflate 설명 (0) | 2022.05.24 |
findviewById 성능문제와 대체법 (binding) (0) | 2022.05.23 |
매니페스트에서 액티비티 뒤로가기 설정 (0) | 2022.05.20 |