SharedPreferences에 값이 제대로 들어가는 지 테스트했었는데

 

테스트 할 당시에는 제대로 값이 남아있는 듯 보였으나 나중에 스마트폰을 재부팅한 뒤 다시보니

 

아무런 데이터도 저장되어있지 않은 것을 발견하였다.

 

확인해본 결과 환경설정->어플리케이션 메뉴에서 어플을 찾아 강제종료버튼(작업관리자에 표시되지 않더라도 활성화되어있다)을 누르고 나면

 

다시 실행했을 때 SharedPreferences 값이 하나도 남아있지 않음을 알 수 있었다.

 

메모리 혹은 임시파일 형태로 저장되는 것이라고 추측된다.

 

해결 방법은 다음과 같다.

 

 

SharedPreferences의 Editor를 사용하기 전에 Editor 객체의 clear() 메소드를 호출했더니 문제가 해결되었다.

 

SharedPreferences.Editor ePref = pref.edit();
ePref.clear();
ePref.putStringSet(XXX , XXX);
ePref.apply();

 

 

Editor에 값을 갱신한 후 commit() 또는 apply()를 빠뜨리면 아예 저장이 되지 않으므로 주의하자.

 

또한 clear()를 호출한 후에는 SharedPreferences 값이 지워지므로 보존해야 할 데이터는 따로 마련한 변수 등에 저장해두어야 한다.

Posted by Kugi

댓글을 달아 주세요




안드로이드의 SharedPreferences.Editor에는

비슷한 역할을 하는 apply()와 commit() 두 개의 메소드가 존재한다.

 

이 둘의 차이점을 알아보자.

 

(*아래 내용은 http://developer.android.com/reference/android/content/SharedPreferences.Editor.html 의 영어 원문 일부를 번역한 것이다.)

 

 

public abstract boolean commt()

 

해당 Editor에서 변경한 preferences 값을 이 Editor의 SharedPreferences 객체에 전달한다.

 

두 개의 Editor가 동시에 preferences를 수정 중이라면 마지막에 호출된 commit()가 적용된다.

 

만약 반환값을 필요로 하지 않는다면 apply()를 써도 좋다.

 

반환값: 변경한 값이 성공적으로 저장장치에 반영되면 true를 반환한다.

 

 

public abstract void apply()

 

해당 Editor에서 변경한 preferences 값을 이 Editor의 SharedPreferences 객체에 전달한다.

 

자동적으로, 원래 SharedPreferences 안의 내용이 무엇이었든간에 요청받은 값으로 내용을 대체한다.

 

두 개의 Editor가 동시에 preferences를 수정 중이라면 마지막에 호출된 apply()가 적용된다.

 

저장공간에 지속적인 동기를 유지하며 preferences를 작성하는 commit()과는 달리,

 

apply()는 메모리 내의 SharedPreferences를 즉시 변경하지만 디스크로의 반영은 비동기적으로 시작되며

 

작업 실패에 대한 어떠한 알림도 받을 수 없다.

 

SharedPreferences는 프로세스 내에서 싱글톤 방식의 인스턴스이기 때문에

 

만약 반환 값을 필요로 하지 않는다면 commit() 대신에 apply()를 쓰는 것이 안전하다.

 

apply()의 경우 안드로이드 컴포넌트의 라이프사이클 및 디스크 쓰기의 상호작용을 신경 쓸 필요가 없다.

 

구조적으로 apply()를 한 후에 이루어지는 in-flight 디스크의 쓰기는 상태(state) 전환이 이루어지기 전에 완료되도록 되어있다.

Posted by Kugi

댓글을 달아 주세요

  1. name 2014.12.27 17:38  댓글주소  수정/삭제  댓글쓰기

    좋은 정보 감사합니다!
    근데 SharedPreferences는 프로세스 내에서 싱글톤 방식의 인스턴스이기 때문에
    만약 반환 값을 필요로 하지 않는다면 commit() 대신에 apply()를 쓰는 것이 안전하다는 논리가 잘 이해가 안됩니다..
    좀 더 자세한 설명을 들을수 있을까요

    • Kugi 2014.12.27 21:33 신고  댓글주소  수정/삭제

      마지막 호출만 적용되는 commit()과 달리 apply()는 호출될 때마다 SharedPreferences 내용을 바꿔주기 때문입니다.

  2. 사긔 2016.10.04 16:50 신고  댓글주소  수정/삭제  댓글쓰기

    좋은 글 감사합니다! 노란 밑줄 뜨면서 apply로 변경하라기에 무슨 차이인가 했더니 이해하기 쉽게 설명해주셔서 도움이 되었습니다




안드로이드에서 현재 시간을 알아내기 위해서는 여러 가지 방법이 있겠지만 그 중에서 한 가지를 소개하자면

 

java.util.Calendar 오브젝트를 이용하는 것이다. java.util에 포함되어있기 때문에 물론 안드로이드 뿐만 아니라 일반 자바 프로젝트에서도 이용 가능하다.

 

다음은 사용 예시이다.

 

public static String GetCurrentTime() {
	String time = "";
	Calendar cal = Calendar.getInstance();
	time = String.format("%04d-%02d-%02d-%02d-%02d-%02d-%03d",
			cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH),
			cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), cal.get(Calendar.MILLISECOND));
		
	return time;
}

 

출력되는 포맷은 편의에 맞게 고치면 된다.

이 때 cal.get(Calendar.MONTH)는 "반환값+1"이 실제 달 수이므로 주의해야 한다.

0~12까지의 값을 반환하며 이는 각각 다음과 같이 매치된다.

  0 JANUARY
  1 FEBRUARY
  2 MARCH
  3 APRIL
  4 MAY
  5 JUNE
  6 JULY
  7 AUGUST
  8 SEPTEMBER
  9 OCTOBER
 10 NOVEMBER
 11 DECEMBER
 12 UNDECIMBER

 

시간(hour)을 얻어오는 cal.get(Calendar.HOUR_OF_DAY)는 24시 표현으로 시간 값으로 반환한다.

Posted by Kugi
TAG android, Java

댓글을 달아 주세요




개발 환경을 새롭게 세팅하면서 이클립스 및 안드로이드 개발 툴 등을 새로 설치하게 되었다.

 

이클립스 : eclipse-jee-juno-SR1

안드로이드 sdk : android-sdk_r21.1-windows

 

(jdk는 미리 설치하였으며 버전은 별로 중요하지 않다.)

 

이클립스 Help 메뉴의 "Install New Software..." 를 통해 ADT를 설치하였는데 (Android ADT - http://dl-ssl.google.com/android/eclipse)

 

 

(여기까지의 과정에 대해서는 생략)

 

설치가 끝났는데도 ADT 관련 툴바 아이콘 및 메뉴가 보이지 않았다.

 

설치가 제대로 되지 않은 것인가 의심이 되었으나 찾아보니 결국 문제는 아이콘 및 메뉴가 표시되어있지 않은 것 뿐이었다.

 

해결 방법은 다음과 같다.

 

(이하의 방법을 이미 적용한 후 알아차린 것인데, Open Perspective에서 "Java" perspective를 열면 그냥 문제 해결인 듯 하다.)

 

 

 

굳이 Java EE perspective에서 ADT를 이용하고자 한다면 다음의 단계를 따라하면 된다.

 

 

 

Posted by Kugi

댓글을 달아 주세요

  1. 검색자 2013.03.12 20:39  댓글주소  수정/삭제  댓글쓰기

    헤매던 도중 님의 포스팅으로 바로 해결되었네요! ^^ 감사합니다.

  2. Kugi 2013.06.07 20:09 신고  댓글주소  수정/삭제  댓글쓰기

    덕분에 해결했습니다. 행운이 있길 [검열삭제]!!

    • Kugi 2013.06.07 20:11 신고  댓글주소  수정/삭제

      '고맙습니다'님
      심정은 이해가 가지만 다음부턴 댓글을 달 때
      그러한 표현은 삼가 주시면 좋겠습니다. 감사합니다.

  3. boram 2013.07.18 00:43  댓글주소  수정/삭제  댓글쓰기

    덕분에 문제가 빨리 풀렸네요..설마 거기에 들어가 있을줄이야.ㅠㅠ 감사해요

  4. hyshin 2014.01.22 11:26 신고  댓글주소  수정/삭제  댓글쓰기

    습관적으로 EE 설치했더니 이런 사태가... ^^;;
    올려주신 정보 덕분에 잘 해결했습니다. 감사합니다 ^^

  5. BBBBBBBBBB 2014.05.19 09:46  댓글주소  수정/삭제  댓글쓰기

    진짜 감사요 이렇게하니까 나오내요 휴 ....다행 아우 진짜 어렵내요 ㅠㅠㅠㅠ아무튼 고맙습니다 ^^

  6. junsul84 2015.05.13 15:02  댓글주소  수정/삭제  댓글쓰기

    와 찾았어요 감사합니다!!! ㅎㅎ




안드로이드 프로그래밍을 위해 액티비티 레이아웃 xml 파일을 작업하다 보면

 

다음과 같은 Warning을 만날 수 있다.

 

[Accessibility] Missing contentDescription attribute on image

 

ImageView를 추가하고 이에 대한 contentDescrioption을 빼먹었다는 뜻이다.

 

무시해도 상관은 없지만 노란 경고 표시가 보기 싫다면

 

이 경고 메시지를 없애기 위한 3가지 방법이 있다.

 

첫번째 방법은 경고가 말하는대로 빠뜨린 contentDescription을 추가해주는 방법이다.

 

다음과 같이

 

android:contentDescription="@string/contentDescription"

 

를 추가해주면 경고가 사라진다.

 

 

 

contentDescription을 일일히 써주는게 싫다면 개별적인 경고를 무시하는 방법도 있다.

 

다음과 같이

 

tools:ignore="ContentDescription"

 

를 추가해주면 되는데, 이 때 tools를 사용하기 위해서는

 

xmlns:tools="http://schemas.android.com/tools"

 

가 추가되어있어야 하며 그렇지 않으면

 

error: Error parsing XML: unbound prefix

Attribute is missing the Android namespace prefix

 

이러한 에러가 생긴다.

 

이 방법을 적용하면 아래 이미지에서 볼 수 있듯이, ignore를 추가해준 부분에 대해서만 경고가 사라지게 된다.

 

 

 

마지막으로, 이상의 방법들이 모두 귀찮다면 아예 해당하는 모든 경고를 무시하는 방법이 있다.

 

이클립스의 메뉴중에서

 

[Windows -> Preferences -> Android -> Lint Error Checking]

 

을 찾아가서 contentDescription 항목을 warning 레벨에서 Ignore 레벨로 바꾸어주면 된다.

 

Posted by Kugi

댓글을 달아 주세요

  1. ds 2013.09.10 15:16  댓글주소  수정/삭제  댓글쓰기

    해당 자료 에러가 있네요..
    마지막 ignore 무턱대고 체크하면 전체 에러 발생합니다..

    • Kugi 2013.09.10 21:03 신고  댓글주소  수정/삭제

      전체 에러라는게 무슨 에러를 말씀하시는지요?
      다이얼로그 리스트의 ContentDescription 항목을 선택하고 Ignore로 설정하셔야 합니다.