Programing

ContentProviderClient 대 ContentResolver를 사용하여 콘텐츠 제공자에 액세스

lottogame 2020. 11. 28. 08:32
반응형

ContentProviderClient 대 ContentResolver를 사용하여 콘텐츠 제공자에 액세스


Android 콘텐츠 제공 업체에 대한 설명서에서는에서 얻은를 사용 하여 콘텐츠에 액세스하는 ContentResolver방법을 설명 getContentResolver()합니다.

그러나 ContentProviderClient에서 얻을 수있는 getContentResolver().acquireContentProviderClient(authority). ContentResolver공급자의 콘텐츠에 액세스하기 위해 에서 사용할 수있는 것과 동일한 방법을 제공하는 것 같습니다 .

직접 사용하는 ContentProviderClient대신 언제 사용해야 ContentResolver합니까? 이점은 무엇입니까?


귀하의 안드로이드 장치에는 많은 데이터베이스가 있으며 각 데이터베이스는 고유 한 콘텐츠 기관에 의해 식별됩니다. 이것은 content : // uri의 "도메인 이름"에 해당하는 부분이며 첫 번째 슬래시 앞의 모든 것입니다.

ContentResolver에서 String contentAuthority로의 매핑을 제공하는 데이터를 저장 합니다 ContentProvider. 당신이 호출 할 때 ContentResolver.query()update()또는 무엇을 가지고, URI를 따로 구성 요소로 해석되면, contentAuthority 문자열이 확인되고, 컨텐트 리졸버는 일치하는 문자열이지도를 검색하고 오른쪽 공급자에 쿼리를 지시한다. URI가 호출마다 다를 수 있고 contentAuthority도 다를 수 있기 때문에이 비용이 많이 드는 검색은 모든 단일 호출 중에 발생합니다. 또한 특정 공급자에 대한 연결을 설정하고 해제하는 데 약간의 비용이 소요될 수 있습니다. 통화간에 재사용 할 수 없습니다. 나는 거기에 관련된 오버 헤드가 확실하지 않습니다. 꽤 깊은 OS 레벨 코드입니다.

반대로 전화 acquireContentProviderClient(authority)하면 "무엇을 제공해야합니까?" 조회는 한 번 수행 ContentProviderClient되며 기본적으로 ContentProvider. (스레드 간 통신 및 동시성 잠금을 포함하는 공급자와 사용자 사이에는 약간의 접착제가 있습니다.) 그러나를 사용할 때 귀하 ContentProviderClient가 요청한 권한에 대해 제공자에게 직접 이야기하게됩니다. 이렇게하면 "내가 원하는 공급자"를 지속적으로 다시 계산하는 낭비가 사라집니다.

참고 :acquireContentProviderClient () 문서 : 당신이 ContentProviderClient를 얻을 경우, "발신자 그들이 호출하여 공급자와 함께 할 것을 표시해야 ContentProviderClient.release을 () 시스템이 그것을 다른이없는 것으로 판단 공급자를 해제 할 수 있습니다 활동을 유지하는 이유. " 따라서 본질적으로 오래된 클라이언트를 열어두면 Provider가 백그라운드에서 서비스로 계속 실행됩니다. 따라서 정리하는 것을 잊지 마십시오!

요약:

다양한 contentAuthorities에 많은 전화 : 사용 ContentResolver.

같은 기관에 반복 호출 : 확보 및 사용 ContentProviderClient. 완료되면 release ()하는 것을 잊지 마십시오.


좋습니다. 그러나 ContentProvider 가 Activity와 동일한 프로세스에서 실행될 때만 작동합니다 .

방법에 대한 문서의 참고 사항 getLocalContentProvider():

ContentProvider가 다른 프로세스에서 실행중인 경우 null이 반환됩니다. 공급자와 동일한 프로세스에서 실행 중이며 구현 세부 정보에 직접 액세스하려는 경우 사용할 수 있습니다.


또 다른 가져 오기 차이점은 ContentProviderClient를 사용자 지정 공급자 개체로 캐스팅하고 CRUD 외에 다른 메서드에 액세스 할 수 있다는 것입니다.

ContentProvider cp = getContentResolver().acquireContentProviderClient(mCurUri).getLocalContentProvider();
yourProvider fld = (yourProvider)cp;
fld.query(...);           // you can query as ContentResolver
fld.addFolder(newFolder); // also can invoke the extend method of your custom ContentProvider

다음과 같은 차이점을 발견했습니다. 앱 A에 사용자 지정 콘텐츠 제공 업체를 작성했습니다. 앱 B에 홈 화면 위젯을 작성했습니다. 위젯에서 ContentResolver를 통해 앱 A의 ContentProvider에 액세스하려고 할 때 "제공 업체를 찾지 못했습니다. 정보 "오류. 대신 ContentResolver를 통해 ContentProviderClient를 얻고 ContentProviderClient를 통해 쿼리하면 작동합니다. 아무것도 변경하지 않고 ContentResolver 대신 ContentProviderClient 만 사용했습니다. 나는 그 행동에 대한 실제 설명이 없으며 인터넷에서 왜 그런지에 대한 정보를 찾지 못했습니다. 앱 B의 활동에서 시도하지 않았기 때문에 이것이 위젯의 ​​특별한 특징인지 모르겠습니다 (앱 B는 활동이없는 단순한 위젯 임).


ContentProviderClient의 사용법 중 하나는 테스트에서 ContentProvider의 일부 메서드에 액세스하는 데 유용합니다. 예를 들어 여러 콘텐츠 공급자를 인스턴스화하는 여러 테스트를 방지하기 위해 단위 테스트에서 shutdown () 메서드를 사용합니다 .

다음 ContentProvider#shutdown()과 같이 구현 하십시오.

@Override
public void shutdown() {
    openHelper.close();
    super.shutdown();
}

그리고 시험 방법의 끝에서 호출 shutdown()를 사용하여 ContentProviderClient다른 테스트가 콘텐츠 공급자를 사용할 수 있도록 테스트를 청소 :

getContext()
       .getContentResolver()
       .acquireContentProviderClient(URI)
       .getLocalContentProvider()
       .shutdown();

참고 URL : https://stackoverflow.com/questions/5084896/using-contentproviderclient-vs-contentresolver-to-access-content-provider

반응형