SharedPreferences의 commit ()과 apply ()의 차이점은 무엇입니까?


431

SharedPreferences내 안드로이드 앱에서 사용 하고 있습니다. 둘 다 사용하고 있습니다commit()apply()공유 환경 설정에서 및 방법을 하고 있습니다. AVD 2.3을 사용하면 오류가 표시되지 않지만 AVD 2.1에서 코드를 실행하면 apply()메서드에 오류가 표시됩니다.

이 둘의 차이점은 무엇입니까? 그리고 commit()환경 설정 값을 아무 문제없이 저장할 수 있습니까?


115
이것은 1 년 전이지만 어쨌든 그것에 대해 언급 할 것입니다. 분명히 대답 할 수있는 대답은 없습니다 . 동 기적 인 apply()동안 디스크 I / O를 비동기 적으로 수행 commit()합니다. 따라서 실제로 commit()UI 스레드에서 호출해서는 안됩니다 .
michiakig 2016 년

여러 SharedPreferences.Editor 개체를 사용하는 경우 마지막으로 호출 한 개체가 우선합니다 apply(). 따라서 응용 프로그램에서 하나의 SharedPreferences.Editor 만 사용하고 있는지 확인하는 apply()대신 commit()안전하게 사용할 수 있습니다 .
aoeu

2
Android Studio Lint 경고에 따라 commit ()은 즉시 및 동 기적으로 데이터를 저장합니다. 그러나 apply ()는 백그라운드에서 비동기 적으로 저장하여 성능을 향상시킵니다. 따라서 반환 유형에 신경 쓰지 않으면 (데이터가 성공적으로 저장되었는지 여부) commit ()보다 apply ()가 선호됩니다.
Rahul Raina

사용할 때 Lint 경고를 비활성화하는 방법이 commit()있습니까?
QED

답변:


653

apply()2.3에 추가되었으므로 성공 또는 실패를 나타내는 부울 반환 하지 않고 커밋 합니다.

commit()반환 진정한 작품을 저장 한 경우, 거짓 그렇지.

apply() Android 개발자 팀은 거의 아무도 반환 값을 알지 못 했으므로 비동기식이므로 적용이 더 빠릅니다.

http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#apply ()


8
이 답변은 사실이지만 위의 @spacemanaki 님의 의견도 역시 가치있는 정보를 포함하고 있다고 생각합니다.
Aksel Fatih

58
commit ()은 즉시 영구 저장소에 데이터를 기록하지만 apply ()는 백그라운드에서 처리합니다.
capt.swag

18
경쟁 조건을 생성합니까?
ChrisMcJava

42
apply ()로 무언가를 쓰고 바로 읽으면 어떻게 되나요? 읽은 것이 나에게 새로운 가치를 제공한다고 보장 되는가? 문서는 apply ()를 실행 한 후 다른 commit ()이 발생하면 apply ()가 디스크에 지속 될 때까지 commit ()이 차단되어 '쓰기'작업과 관련 하여이 문제가 발생하지 않음을 분명히합니다. 하지만 바로 쓰고 쓰고 있다면 어떨까요? 내 테스트에서 최신 값이 반환되지만 이것이 100 % 보장되는지 알고 싶습니다.
Tiago

22
그것은) (해당과 (커밋의 인스턴스)를 교체 참조하는 것이 안전 developer.android.com/reference/android/content/...
티그 Sarkisian

221

tl; dr :

  • commit() 데이터를 쓴다 동기식으로 (스레드가 호출 한 스레드 차단). 그런 다음 작업 성공 여부 를 알려줍니다 .
  • apply() 기록 할 데이터를 예약합니다 비동기 적 . 그것은 통보하지 않는 작업의 성공에 대해.
  • 당신이 저장하는 경우 apply()getX 메소드 즉시 읽으면 값이 리턴됩니다!
  • apply()어느 시점에서 전화 했는데 여전히 실행중인 경우commit() 모든 과거의 적용-를 호출 할 때까지 차단 하고 현재 커밋 통화를 완료됩니다.

더 자세한 정보는 SharedPreferences.Editor 설명서의 :

commit () 과 달리 환경 설정을 동기식으로 영구 스토리지에 기록합니다. , ) (적용 즉시 메모리 된 SharedPreferences로의 변경을 커밋하지만 비동기 디스크에 커밋하고 모든 오류를 통지하지 않습니다 시작합니다 . apply ()가 여전히 미해결 된 상태에서이 SharedPreferences의 다른 편집기가 일반 commit ()을 수행하는 경우 commit ()은 확약 자체뿐만 아니라 모든 비동기 확약이 완료 될 때까지 차단됩니다.

SharedPreferences 인스턴스는 프로세스 내의 싱글 톤이므로 반환 값을 이미 무시하고있는 경우 commit () 인스턴스를 apply ()로 바꾸는 것이 안전합니다.

SharedPreferences.Editor 인터페이스는 직접 구현 될 것으로 예상되지 않습니다. 그러나 이전에 구현했지만 apply () 누락에 대한 오류가 발생하는 경우 apply ()에서 commit ()을 호출하면됩니다.


19
이것은 apply()비동기식이며 보류중인 쓰기가 향후 호출을 차단 한다는 점을 언급하기 때문에 훨씬 더 나은 대답 commit()입니다.
spaaarky21

22

apply () 대신 commit ()을 사용하는 데 문제가 있습니다. 다른 응답에서 이전에 언급 한 것처럼 apply ()는 비동기 적입니다. "문자열 세트"환경 설정에 대한 변경 사항이 영구 메모리에 기록되지 않는다는 문제가 있습니다.

메모리 강제로 인해 시스템에서 프로세스가 종료되면 프로그램의 강제 강제 구금 또는 Android 4.1이 설치된 장치에 설치된 ROM에있는 경우 발생합니다.

환경 설정을 유지하려면 "appmit ()"대신 "apply ()"를 사용하는 것이 좋습니다.


동시 스레딩으로 인해 문제가 관련되지 않았습니까? apply ()를 보낸 후에는 추가 한 내용을 읽는 동안 잠시 기다려야합니다. 그렇지 않으면 apply ()의 작업자 스레드가 변경 사항을 커밋하기 전에 UI 스레드가 읽기를 시도합니다.
Marco Altran

문자열 세트와 관련하여 stackoverflow.com/questions/16820252/…
Tapirboy

@JoseLSegura-문서는 다른 방법으로 제안합니다. developer.android.com/intl/ja/reference/android/content/… "Android 컴포넌트 수명주기와 디스크에 apply () 쓰기와의 상호 작용에 대해 걱정할 필요가 없습니다. 상태를 전환하기 전에 apply ()에서 기내 디스크 쓰기가 완료되었는지 확인하십시오. " 당신이보고있는 것이 Android의 버그인지, 그렇다면 최신 버전에서 수정되었는지 궁금합니다.
ToolmakerSteve

라이브러리 "ProcessPhoenix"를 사용하여 앱을 재설정하는 것과 동일한 문제가 발생합니다. 재설정을 수행하기 직전에 기본 설정을 저장했는데 "적용"이 작동하지 않았습니다.
ElYeante

14

apply ()를 사용하십시오.

RAM에 변경 사항을 즉시 기록하고 대기 후 내부 저장 장치 (실제 기본 설정 파일)에 기록합니다. 커밋은 변경 사항을 동 기적으로 파일에 직접 씁니다.


14
  • commit()동 기적 apply()으로 비동기

  • apply() 무효 기능입니다.

  • commit() 새 값이 영구 저장소에 성공적으로 기록되면 true를 반환합니다.

  • apply() 상태를 전환하기 전에 완료를 보장하므로 Android 구성 요소 수명주기에 대해 걱정할 필요가 없습니다.

당신이에서 반환 된 사용 가치를 해달라고하면 commit()당신이 사용하고있는 commit()메인 스레드에서 사용하는 apply()대신 commit()


13

워드 프로세서의 차이 꽤 좋은 설명 제공 apply()commit():

commit()기본 설정을 동기식 스토리지에 동 기적으로 기록하는와 달리 , apply()변경 사항을 메모리 내에서 SharedPreferences즉시 커밋하지만 디스크에 대한 비동기 커밋을 시작하면 실패에 대한 알림을받지 않습니다. 이것에 대한 다른 편집기 SharedPreferences가 a를 여전히 수행하는 commit()동안 규칙적으로 수행 하는 경우 apply(), commit()모든 비동기 커밋이 완료 될 때까지 커밋 자체가 차단됩니다. 으로 SharedPreferences인스턴스는 프로세스 내에서 싱글은, 그것의 인스턴스 교체하는 것이 안전 commit()apply()이미 반환 값을 무시한다면합니다.


6

javadoc에서 :

기본 설정을 동기식 스토리지에 동기식으로 기록하는 commit ()과 달리 apply ()는 변경 사항을 메모리 내 SharedPreferences에 즉시 커미트하지만 디스크에 대한 비동기 커미트를 시작하므로 실패에 대한 알림을받지 않습니다. 이 applyPreferences의 다른 편집기가> apply ()가 여전히 미결 상태 인 동안 일반 commit ()을 수행하는 경우 commit ()은 모든 비동기 커밋이 완료 될 때까지 커밋 자체를 차단합니다.


1

commit ()과 apply ()의 차이점

SharedPreference를 사용할 때이 두 용어로 혼동 될 수 있습니다. 기본적으로 그것들은 아마도 같을 것이므로 commit ()과 apply ()의 차이점을 명확히하자.

1. 반품 가치 :

apply()성공 또는 실패를 나타내는 부울을 반환하지 않고 커밋합니다. commit()는 저장이 작동하면 true를, 그렇지 않으면 false를 반환합니다.

  1. 속도:

apply()가 더 빠르다. commit()더 느립니다.

  1. 비동기식 vs 동기식 :

apply(): 비동기 commit(): 동기

  1. 원자 :

apply(): 원자 commit(): 원자

  1. 오류 알림 :

apply(): 아니오 commit(): 예


apply()"보다 빠른" 방법은 commit()무엇입니까? 그들은 본질적으로 스레드의 루퍼에 넣을 동일한 작업을 나타냅니다. 백그라운드 commit()에서 작업을 수행하면서 메인 루퍼에 해당 작업 apply()을 저장하여 메인 루퍼에 디스크 I / O 작업이 없도록합니다.
Taseer

기본 설정을 동기식 스토리지에 동기식으로 기록하는 commit ()과 달리 apply ()는 변경 사항을 메모리 내 SharedPreferences에 즉시 커미트하지만 디스크에 대한 비동기 커미트를 시작하므로 실패에 대한 알림을받지 않습니다. 이 SharedPreferences의 다른 편집기가 apply ()가 여전히 미해결 상태 인 동안 일반 commit ()을 수행하는 경우 commit ()은 모든 비동기 커밋이 완료 될 때까지 차단되며 커밋 자체는 DOC 개발자를
Chanaka Weerasinghe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.