Android 기본 요약: (11) ContentResolver 와 ContentProvider 가 어떻게 연결 되 었 는 지
관련 류
froyo/frameworks/base/core/java/android/app/ApplicationContext.java
froyo/frameworks/base/core/java/android/app/ActivityThread.java
froyo/frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
우리 가 휴대 전 화 를 시작 한 후에 activity, Activity Thread 를 시작 해 야 한다 면 Activity Manager Service 가 역할 을 발휘 하기 시 작 했 습 니 다. 여기 서 자세히 설명 하지 않 습 니 다.
우리 가 진정 으로 activity 를 시작 할 때, 우 리 는 현재 응용 프로그램의 응용 프로그램 Context 를 전송 합 니 다. 응용 프로그램 Context 실례 는 mContext Resolver 대상 을 가지 고 있 습 니 다. 이 대상 은 응용 프로그램 Context 의 내부 클래스 응용 프로그램 ContentResolver 에 대응 합 니 다.
activity 가 getContentResolver () 를 호출 할 때 현재 applicationContext 의 mContextResolver 를 실제 호출 합 니 다.
효과 도 를 살 펴 보 자.
검은색 의 계승 관계 로 인해 우 리 는 빨간색 의 호출 관 계 를 얻 을 수 있 습 니 다. 우 리 는 효과 도 를 보면 알 수 있 습 니 다. 그들 두 사람 은 어떻게 파일 을 건 너 뛰 어 직접 연결 되 었 는 지 알 수 있 습 니 다.그러면 우 리 는 많은 부분 을 절약 하고 시간 도 절약 할 수 있 습 니 다. 그러면 우리 도 실 수 를 하기 쉽 지 않 습 니 다. 그러면 우 리 는 우리 의 업무 효율 을 크게 향상 시 킬 것 입 니 다.
코드 세 션 은 다음 과 같 습 니 다:
Activity 에서 ContextWrapper 를 호출 하 는 방법getContentResolver() {
mBase.getContentResolver();
}
그리고 Application Context 로 호출 되 는 방법 입 니 다.getContentResolver() {
return mContentResolver;
}
Java 코드:mContentResolve r = new ApplicationContentResolver(this, mainThread);
private static final class ApplicationContentResolver extends
ContentResolver {
public ApplicationContentResolver(Context context,
ActivityThread mainThread) {
super(context);
mMainThread = mainThread;
}
@Override
protected IContentProvider acquireProvider(Context context, String name) {
return mMainThread.acquireProvider(context, name);
}
@Override
public boolean releaseProvider(IContentProvider provider) {
return mMainThread.releaseProvider(provider);
}
private final ActivityThread mMainThread;
}
mContentResolver. query () 를 실행 할 때 부모 클래스 ContentResolver 의 query () 를 호출 합 니 다.public final Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
IContentProvider provider = acquireProvider(uri);
if (provider == null) {
return null;
}
try {
Cursor qCursor = provider.query(uri, projection, selection,
selectionArgs, sortOrder);
if (qCursor == null) {
releaseProvider(provider);
return null;
}
// CursorWrapperInner
return new CursorWrapperInner(qCursor, provider);
} catch (RemoteException e) {
releaseProvider(provider);
return null;
} catch (RuntimeException e) {
releaseProvider(provider);
throw e;
}
}
public final IContentProvider acquireProvider(Uri uri) {
if (!SCHEME_CONTENT.equals(uri.getScheme())) {
return null;
}
String auth = uri.getAuthority();
if (auth != null) {
return acquireProvider(mContext, uri.getAuthority());
}
return null;
}
이 때 하위 클래스 인 스 턴 스 aquire Provider (Context, name) 를 호출 합 니 다.mMainThread.acquireProvider (context, name);
Java 코드:public final IContentProvider acquireProvider(Context c, String name) {
IContentProvider provider = getProvider(c, name);
if (provider == null)
return null;
IBinder jBinder = provider.asBinder(); // binder , 。
synchronized (mProviderMap) {
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
if (prc == null) {
mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
} else {
prc.count++;
} // end else
} // end synchronized
return provider;
}
private final IContentProvider getProvider(Context context, String name) {
synchronized (mProviderMap) {
final ProviderRecord pr = mProviderMap.get(name); // ActivityThread Provider
if (pr != null) {
return pr.mProvider;
}
}
// , , install, 。
IActivityManager.ContentProviderHolder holder = null;
try {
holder = ActivityManagerNative.getDefault().getContentProvider(
getApplicationThread(), name);
} catch (RemoteException ex) {
}
if (holder == null) {
Log.e(TAG, "Failed to find provider info for " + name);
return null;
}
if (holder.permissionFailure != null) {
throw new SecurityException("Permission
+ holder.permissionFailure + " required for provider
+ name);
}
IContentProvider prov = installProvider(context, holder.provider,
holder.info, true);
// Log.i(TAG, "noReleaseNeeded=" + holder.noReleaseNeeded);
if (holder.noReleaseNeeded || holder.provider == null) {
// We are not going to release the provider if it is an external
// , ,
// 。
// Log.i(TAG, "*** NO RELEASE NEEDED");
synchronized (mProviderMap) {
mProviderRefCountMap.put(prov.asBinder(), new ProviderRefCount(
10000));
}
}
return prov;
}
위의 코드 if (provider = = null) 뒤에 반환 값 이 있 습 니 다. 이 반환 값 은 반드시 비어 있어 야 합 니 다. 다른 것 을 쓰 지 마 세 요. 뒤의 판단 도 모두 비어 있다 고 판단 합 니 다. 그러면 우 리 는 contentResolver 와 contentProvider 가 연결 되 어 있 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.