하나의 액티비티에서 작업을 한다음 다음 액티비티로 넘어가더라도 이전의 액티비티의 상태정보를 가지고 작업을 할 수 있어야 한다.
이런 경우에 액티비티의 수명주기 메서드인 onPause(), onResume()을 이용해서 액티비티가 멈추거나 다른 액티비티에 의해 가려질 때 데이터를 저장하고, 액티비티가 다시 보이거나 새로 시작될 때 저장된 데이터를 호출하는 방식으로 상태정보를 저장하고 가져올 수 있다.
SharedPrefereces타입은 데이터를 저장하는 기능을 제공하는 클래스이다.
SharedPrefereces는 그 자체로 인스턴스를 생성하고 참조할 수 없는 인터페이스라서 참조하는 방법은 Context의 자손클래스에 정의된 getSharedPrefereces()메서드를 호출해서 참조할 수 있다. 이 메서드의 반환 타입이 SharedPrefereces이기 때문이다.
그리고 실제로 데이터를 저장하는 기능을 하는 타입은 Editor인터페이스인데 이 Editor는 SharedPrefereces인터페이스의 내부 인터페이스로 정의되어 있기 때문에 SharedPrefereces.Editor로 타입의 참조변수를 만들고 SharedPrefereces타입의 참조변수의 editor()메서드를 Editor가 참조받을 수 있다.
설명한대로 코드를 만들면..
SharedPreferences sp = getSharedPreferences("testKey" , Activity .MODE_PRIVATE );
SharedPreferences .Editor editor = sp.edit();
//데이터를 저장하는 방법
editor.putInt("count" ,count);
editor.commit();
//데이터를 불러오는 방법
if(sp != null && sp.contains("testKey" )){
int result = sp.getInt("count" , 0 );
}
//데이터를 초기화 하는 방법
editor.clear();
editor.commit();
위와 같은 방식으로 데이터를 저장하고 불러오고, 삭제할 수 있다.
그리고 데이터를 저장하거나 삭제할 때는 꼭 commit()메서드를 호출해야 적용이 된다.
다음은 액티비티 수명주기 메서드와 SharedPrefereces를 이용해서 데이터를 저장하고, 불러오고, 삭제하는 방식으로 테스트 해 본 코드이다.
activity_cycle.xml 접기
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.choonie.flagactivity.CycleActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="라이프사이클!"
android:textSize="30dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="callOtherActivity"
android:text="다른액티비티호출" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="countMethod"
android:text="카운트올리기" />
</LinearLayout >
접기
CycleActivity.java 접기
public class CycleActivity extends AppCompatActivity {
//테스트 상태 코드인 카운트 변수
//임의로 증가시킨 카운트를 다른 액티비티로 넘어가거나 작업이 중지 되면 현재 카운트를 저장한다.
//그리고 다시 이 액티비티로 돌아올 경우 저장된 카운트를 다시 불러온다
//어플리케이션이 종료되는(소멸되는) destroy때는 카운트를 clear한다.
private int count = 0 ;
@Override
protected void onCreate (Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
setContentView(R .layout.activity_cycle);
Toast .makeText(this, "onCreate 메서드에 들어옴" , Toast .LENGTH_LONG ).show();
}
public void countMethod (View v ) {
count = count + 1 ;
}
@Override
protected void onStart () {
super.onStart();
Toast .makeText(this, "onStart 메서드에 들어옴" , Toast .LENGTH_LONG ).show();
}
@Override
protected void onResume () {
super.onResume();
int result = restoreData();
Toast .makeText(this, "onResume 메서드에 들어옴 >>" +result+"부터 센다." , Toast .LENGTH_LONG ).show();
}
@Override
protected void onPause () {
super.onPause();
saveData();
Toast .makeText(this, "다른 액티비티가 호출되서 onPause 메서드에 들어옴 >>" +count+"부터 세는걸 멈춤" , Toast .LENGTH_LONG ).show();
}
@Override
protected void onStop () {
super.onStop();
Toast .makeText(this, "액비비티가 보이지 않기 때문에 onStop 메서드에 들어옴" , Toast .LENGTH_LONG ).show();
}
public void callOtherActivity (View v ) {
Intent in = new Intent (this, CycleTwoActivity .class);
startActivity(in);
}
public int restoreData (){
SharedPreferences sp = getSharedPreferences("testKey" , Activity .MODE_PRIVATE );
if(sp != null && sp.contains("count" )){
count = sp.getInt("count" , 0 );
}
return count;
}
public void saveData (){
SharedPreferences sp = getSharedPreferences("testKey" , Activity .MODE_PRIVATE );
SharedPreferences .Editor editor = sp.edit();
editor.putInt("count" ,count);
editor.commit();
}
public void clearData (){
SharedPreferences sp = getSharedPreferences("testKey" , Activity .MODE_PRIVATE );
SharedPreferences .Editor editor = sp.edit();
editor.clear();
editor.commit();
}
@Override
protected void onDestroy () {
super.onDestroy();
clearData();
Toast .makeText(this, "액티비티가 종료되기 전이기 때문에 onDestroy 메서드에 들어옴" , Toast .LENGTH_LONG ).show();
}
}
접기
activity_cycle_two.xml 접기
<?xml version="1.0" encoding="utf-8" ?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.choonie.flagactivity.CycleTwoActivity" >
<TextView
android:id="@+id/texted"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30dp"
android:text="액티비티2"
/>
<Button
android:layout_below="@+id/texted"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="액티비티1으로 간다"
android:onClick="backCycleActivity" />
</RelativeLayout >
접기
CycleTwoActivity.java 접기
public class CycleTwoActivity extends AppCompatActivity {
@Override
protected void onCreate (Bundle savedInstanceState ) {
super.onCreate(savedInstanceState);
setContentView(R .layout.activity_cycle_two);
}
public void backCycleActivity (View v ){
Intent in = new Intent (this, CycleActivity .class);
in.setFlags(Intent .FLAG_ACTIVITY_SINGLE_TOP );
startActivity(in);
}
@Override
protected void onPause () {
super.onPause();
Toast .makeText(this, "다른 액티비티가 호출되서 onPause 메서드에 들어옴(CycleTwoActivity)" , Toast .LENGTH_LONG ).show();
}
@Override
protected void onStop () {
super.onStop();
Toast .makeText(this, "액비비티가 보이지 않기 때문에 onStop 메서드에 들어옴(CycleTwoActivity)" , Toast .LENGTH_LONG ).show();
}
@Override
protected void onDestroy () {
super.onDestroy();
Toast .makeText(this, "액티비티가 종료되기 전이기 때문에 onDestroy 메서드에 들어옴(CycleTwoActivity)" , Toast .LENGTH_LONG ).show();
}
}
접기