https://developer.android.com/reference/android/content/ContentProvider
public abstract class ContentProvider extends Object implements ComponentCallbacks2
μ½ν μΈ νλ‘λ°μ΄λλ μλλ‘μ΄λ μ ν리μΌμ΄μ λ€ μ€μ μ€μ ꡬμ±μμλ€ μ€ νλλ‘, μ ν리μΌμ΄μ λ€μ μ½ν μΈ λ₯Ό μ 곡ν©λλ€. μ½ν μΈ νλ‘λ°μ΄λλ λ°μ΄ν°λ₯Ό μΊ‘μννκ³ λ¨μΌ ContentResolver μΈν°νμ΄μ€λ₯Ό ν΅ν΄ μ ν리μΌμ΄μ λ€μ μ΄κ²μ μ 곡ν©λλ€. μ½ν μΈ νλ‘λ°μ΄λλ μ¬λ¬ μ ν리μΌμ΄μ λ€ μ¬μ΄μμ λ°μ΄ν°λ₯Ό 곡μ ν΄μΌν λλ§ νμν©λλ€. μλ₯Ό λ€μ΄, μ°λ½μ² λ°μ΄ν°λ μ¬λ¬ μ±λ€μμ μ¬μ©λκ³ , μ½ν μΈ νλ‘λ°μ΄λ μμμ μ μ₯λμ΄μΌλ§ ν©λλ€. λ§μ½ μ¬λ¬ μ ν리μΌμ΄μ λ€ μ¬μ΄μμ λ°μ΄ν°λ₯Ό 곡μ ν νμκ° μλ€λ©΄ SQLiteDatabaseλ₯Ό ν΅ν΄ μ§μ μ μΌλ‘ λ°μ΄ν°λ² μ΄μ€λ₯Ό μ¬μ©ν μ μμ΅λλ€.
μμ²(request)μ ContentResolverλ₯Ό ν΅ν΄μ λ§λ€μ΄μ§κ³ , μμ€ν μ μ£Όμ΄μ§ URIμ κΆνμ μ κ²νκ³ μμ²μ κΆνμ κ°μ§ λ±λ‘λ μ½ν νΈ νλ‘λ°μ΄λλ‘ λ³΄λ λλ€. μ½ν μΈ νλ‘λ°μ΄λλ URIμ λλ¨Έμ§ λΆλΆμ μνλ λλ‘ ν΄μν μ μμ΅λλ€. UriMatcher ν΄λμ€λ URI νμ±μ λμμ£Όμ£ .
ꡬνλμ΄μΌ νλ μ£Όμ λ©μλλ€μ λλ€.
- onCreate() : νλ‘λ°μ΄λλ₯Ό μ΄κΈ°ννλλ° νΈμΆλ©λλ€.
- query(Uri, String[], Bundel, CancellationSignal) : νΈμΆμμκ² λ°μ΄ν°λ₯Ό λ°νν©λλ€.
- insert(Uri, ContentValues) : 컨ν μΈ νλ‘λ°μ΄λλ‘ μ λ°μ΄ν°λ₯Ό μ½μ ν©λλ€.
- update(Uri, ContentValues, Bundle) : μ½ν μΈ νλ‘λ°μ΄λ μμ μ‘΄μ¬νλ λ°μ΄ν°λ₯Ό μ λ°μ΄νΈν©λλ€.
- delete(Uri, Bundle) : μ½ν μΈ νλ‘λ°μ΄λμ λ°μ΄ν°λ₯Ό μμ ν©λλ€.
- getType(Uri) : μ½ν μΈ νλ‘λ°μ΄λ μμ λ°μ΄ν°μ MIME νμ μ λ°νν©λλ€.
β
(insert(Uri, ContentValues), update(Uri,ContentValues, Bundle)κ³Ό κ°μ) λ°μ΄ν° μ κ·Ό λ©μλλ€μ νλ²μ λ§μ μ°λ λ€μμ νΈμΆλ μ μκ³ , λ°λμ thread-safeν΄μΌλ§ ν©λλ€. (onCreate() κ°μ) λ€λ₯Έ λ©μλλ€μ μ ν리μΌμ΄μ μ λ©μΈ μ°λ λμμλ§ νΈμΆλκ³ , λ무 κΈ΄ μμ μ μννλ κ²μ λ°λμ νΌν΄μΌλ§ν©λλ€. μμλλ μ°λ λ λμλ€μ λ©μλ μ€λͺ λ€μ 보μΈμ.
ContentResolverλ‘μ μμ²λ€μ μλμΌλ‘ μ μ ν μ½ν μΈ νλ‘λ°μ΄λ μΈμ€ν΄μ€μ μ λ¬λκ³ , νμ ν΄λμ€λ€μ νλ‘μΈμ€ κ°μ νΈμΆλ€μ μμΈν κ²λ€μ λν΄μλ κ±±μ ν νμκ° μμ΅λλ€.
onCreate
public abstract boolean onCreate()
μ€ννΈμ λμ 컨ν μΈ νλ‘λ°μ΄λλ₯Ό μ΄κΈ°ννκΈ° μν΄ κ΅¬ννμΈμ. μ΄ λ©μλλ μ ν리μΌμ΄μ μ μμ(launch) μκ°μ μ ν리μΌμ΄μ μ λ©μΈ μ°λ λμμ λͺ¨λ λ±λ‘λ μ½ν μΈ νλ‘λ°μ΄λλ€μ νΈμΆλ©λλ€. λ무 κΈ΄ μμ μ μννλ©΄ μλ©λλ€. κ·Έλ κ² νλ€λ©΄ μ€ννΈμ μ΄ μ§μ°λ©λλ€.
μ½ν μΈ νλ‘λ°μ΄λκ° (query(Uri, String[], Bundle, CancellationSignal), insert(Uri, ContentValues)λ±μ ν΅ν΄) μ¬μ©λκΈ° μ κΉμ§ (λ°μ΄ν°λ² μ΄μ€λ₯Ό μ΄κ±°λ, μ κ·Έλ μ΄λ νκ±°λ, μ€μΊνλ κ²μ²λΌ ) μ€μνμ§ μμ μ΄κΈ°νλ μ°κΈ°ν΄μΌ ν©λλ€. μ§μ°λ μ΄κΈ°νλ μ ν리μΌμ΄μ μ μ€ννΈμ μ λΉ λ₯΄κ² μ μ§νκ³ , νλ‘λ°μ΄λκ° λΆνμνλ€λ©΄ λΆνμν μμ μ νΌνκ³ , (full diskμ κ°μ) λ°μ΄ν°λ² μ΄μ€ μλ¬κ° μ± μ€νμ μ€μ§μν€λ κ²μ λ§μ΅λλ€ .
SQLiteλ₯Ό μ¬μ©νλ€λ©΄, SQLiteOpenHelperλ λ°μ΄ν°λ² μ΄μ€λ₯Ό μ½κ² κ΄λ¦¬νλλ‘ νκ³ μ²μ μ¬μ©ν λκΉμ§ μλμΌλ‘ μ€νμ μ§μ°μν€λλ° λμμ΄ λλ μ νΈλ¦¬ν° ν΄λμ€μ λλ€. λ§μ½ SQLiteOpenHelperλ₯Ό μ¬μ©νλ€λ©΄, μ΄ λ©μλμμ SQLiteOpenHelper.getReadableDatabase() λλ SQLiteOpenHelper.getWritableDatabase()λ₯Ό νΈμΆνλ 건 νΌν΄μΌλ§ ν©λλ€. (λμ μ, μ²μ μ€νλ λ λ°μ΄ν°λ² μ΄μ€λ₯Ό μ΄κΈ°ννλ €λ©΄ SQLiteOpenHelper.onOpen(SQLiteDatabase)λ₯Ό μ€λ²λΌμ΄λνμΈμ.)
query
1
public Cursor query (Uri uri, String[] projection, Bundel queryArgs,
CancellationSignal cacellationSignal)
Bundle μμ λ€μ΄κ°λ μΈμλ€μ 쿼리 μμ²μ μ²λ¦¬νλ €λ©΄ μ΄κ²μ ꡬννμΈμ. μΈμλ€μ μ ν΅μ μΈ SQL μ€νμΌμ 쿼리 μΈμλ€μΌ ν¬ν¨ν κ²λλ€. μ‘΄μ¬ν λμ query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal)μ μ±λ¦½λ μ μ½μ λ°λΌ μ²λ¦¬λμ΄μΌ ν©λλ€.
μ ν΅μ μΈ SQL μΈμλ€μ λ²λ€ μμμ λ€μμ ν€λ‘ ννλ μ μμ΅λλ€.
- ContentResolver.QUERY_ARG_SQL_SELECTION
- ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS
- ContentResolver.QUERY_ARG_SQL_SORT_ORDER
Processes and Threadsμμ κΈ°μ λ λ°μ κ°μ΄, μ΄ λ©μλλ μ¬λ¬ μ°λ λμμ νΈμΆ κ°λ₯ν©λλ€.
ν΄λΌμ΄μΈνΈ νΈμΆ μ:
// μΈλ±μ€κ° 30μΈ νμμ μμν΄ 20κ°μ λ μ½λλ₯Ό μμ²ν©λλ€.
Bundle queryArgs = new Bundle();
queryArgs.putInt(ContentResolver.QUERY_ARG_OFFSET, 30);
queryArgs.putInt(ContentResolver.QUERY_ARG_LIMIT, 20);
Cursor cursor = getContentReslver().query(
contentUri, // Content Uriλ κ°λ³ μ½ν
μΈ νλ‘λ°μ΄λμ λ°λΌ λ€λ¦
λλ€.
projection, // String[] μ λ°νν μ΄μ΄ μ΄λ€ κ²μΈμ§ κΈ°μ ν©λλ€.
queryArgs, // 쿼리 μΈμλ€
null); // μ·¨μ(cancellation) signal.
ꡬν μμ :
int recordsetSize = 0x1000; // μ€μ κ°μ ꡬνμ λ°λΌ λ€λ¦
λλ€.
queryArgs = queryArgs != null ? queryArgs : Bundle.EMPTY; // queryArgsκ° non-nullμμ
// νμ€ν ν©λλ€.
int offset = queryArgs.getInt(ContentResolver.QUERY_ARG_OFFSET, 0);
int limit = queryArgs.getInt(ContentResolve.QUERY_ARG_LIMIT, Integer.MIN_VALUE);
MatrixCursor c = new MatrixCursor(PROJECTION, limit);
// 컀μ μμ λ€μ΄κ°λ μμ΄ν
μ μ«μλ₯Ό κ³μ°ν©λλ€.
int numItems = MathUtils.constrain(recordsetSize - offset, 0, limit);
// νμ΄μ§ μλ₯Ό 맀긴 κ²°κ³Ό μ§ν©μ λΉλν©λλ€.
for (int i = offset; i < offset + numItems; i++) {
// λ°μ΄ν°λ‘λΆν° νμ μ±μλλ€.
}
Bundle extras = new Bundle();
c.setExtras(extras);
// μ§μ λλ€λ©΄(if honored. μ€μνλ€κ³ μΈμ λ°λλ€λ©΄) μ΄λ ν QUERY_ARG_* ν€λ ν¬ν¨λ μ μμ΅λλ€.
// μ€μ ꡬνμμ, queryArgs μμ ννλκ³ Cursor μΆλ ₯μλ ννλλ λ κ°μ§λ₯Ό λ§μ‘±νλ ν€λ€λ§
// ν¬ν¨μν€μΈμ. λ§μ½ QUERY_ARG_OFFSETμ΄ queryArgs μμ ν¬ν¨λμμ΄λ (-273κ³Ό κ°μ) μ ν¨νμ§
// μμ κ°μ ν¬ν¨νκ³ μκΈ° λλ¬Έμ 무μλ κ²μ΄κ³ , QUERY_ARG_OFFSETμ μλ΅λμ΄μΌλ§ ν©λλ€.
extras.putStringArray(ContentResolver.EXTRA_HONORED_ARGS, new String[]{
ContentResolver.QUERY_ARG_OFFSET,
ContentResolver.QUERY_ARG_LIMIT
});
extras.putInt(ContentResolover.EXTRA_TOTAL_COUNT, recordsetSize);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
μμΈν ꡬνμ query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal)μ 보μΈμ.
2
public Cursor query(Uri uri, String[] projection, String, selection, Strign[] selectionArgs,
Strign sortOrder, CancellationSignal cancellationSignal)
μ·¨μλ₯Ό μ§μνλ ν΄λΌμ΄μΈνΈμ 쿼리 μμ²μ μ²λ¦¬νλ €λ©΄ μ΄κ²μ ꡬννμΈμ.
Build.VERSION_CODES_O μ΄μμ νκ²ν νλ μ±λ€μ μ΄ λ©μλ λμ μ query(android.net.Uri, java.lang.String[], android.os.Bundle, android.os.CancellationSignal)μ μ€λ²λΌμ΄λνμΈμ.
Processes and Threadsμμ κΈ°μ λ λ°μ κ°μ΄, μ΄ λ©μλλ μ¬λ¬ μ°λ λμμ νΈμΆ κ°λ₯ν©λλ€.
ν΄λΌμ΄μΈνΈ νΈμΆ μ:
// νΉμ λ μ½λλ₯Ό μμ²ν©λλ€.
Cursor managedCursor = managedQuery(
ContentUris.withAppendedId(Contract.People.CONTENT_URI, 2),
projection, // λ°ννλ μ΄μ΄ μ΄λ€ μ΄μΈμ§
null, // WHERE μ (clause. 문ꡬ)
null, // WHERE μ κ°μ λ체
People.NAME + " ASC"); // μ λ ¬ μμ
ꡬν μ:
// SQLiteAueryBuilderλ μ μ ν SQL ꡬ문μ μμ±νλ κ²μ λμμ£Όλ ν΄λμ€ μ
λλ€.
SQLIteQueryBuilder qBuilder = new SQLiteQueryBuilder();
// μ°λ¦¬κ° 쿼리λ₯Ό μ§νν ν
μ΄λΈμ μ€μ ν©λλ€.
qBuilder.setTables(DATABASE_TABEL_NAME);
// λ§μ½ νΉμ λ μ½λ μ«μμμ μΏΌλ¦¬κ° λλλ€λ©΄, μ°λ¦¬λ νΉμ λ μ½λμ λν μμ²μ λ°μ κ²μ΄κ³ ,
// 쿼리 μμ WHERE μ μ μ€μ ν©λλ€.
if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE) {
qBuilder.appendWhere("_id=" + uri.getPathLeafId());
}
// 쿼리λ₯Ό λ§λ€μ΄ μ€λλ€.
Cursor c = qBuilde.query(mDb,
projection,
selection,
selectionArgs,
groupBy,
having,
sortOrder);
c.setNotificationUri(getCotext().getContentResolver(), uri);
return c;
λ§μ½ μ΄ λ©μλλ₯Ό ꡬννλ€λ©΄, μ·¨μ μ νΈ μ€λ²λ‘λκ° λΆκ°λ₯ν μ λ²μ μ μλλ‘μ΄λ νλ μμν¬μμ μ νν μμ μνμ νμ€νκ² νκΈ° μν΄μ μ·¨μ μ νΈλ₯Ό λ°μ§ μλ query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String)μ λ²μ λ λ°λμ ꡬνν΄μΌν©λλ€.
3
public abstract Cursor query(Uri uri,Sring[] projection, String selection,
String[] selectionArgs, String sortOrder)
ν΄λΌμ΄μΈνΈμμ 쿼리 μμ²μ μ²λ¦¬νκΈ° μν΄μ μ΄κ²μ ꡬννμΈμ.
Build.VERSION_CODES.O μ΄μμ νκ²ν νλ μ±λ€μ query(android.net.Uri, java.lang.String[], android.os.Bundle, android.os.CancellationSignal)μ μ€λ²λΌμ΄λ ν΄μΌνκ³ , μ΄ λ©μλμ ꡬνμ μΌλΆλΆμ μ 곡ν΄μΌ ν©λλ€.
Processes and Threadsμμ κΈ°μ λ λ°μ κ°μ΄, μ΄ λ©μλλ μ¬λ¬ μ°λ λμμ νΈμΆ κ°λ₯ν©λλ€.
ν΄λΌμ΄μΈνΈ νΈμΆ μ:
// νΉμ λ μ½λλ₯Ό μμ²ν©λλ€.
Cursor managedCursor = managedQuery(
ContentUris.withAppendedId(Contacts.People.CONTENT_URI, 2),
projection, // λ°νλ νμ΄ μ΄λ€ κ²μΈμ§
null, // WHERE μ
null, // WHERE μ κ° λ체
People.NAME + " ASC"); // μ λ ¬ μμ
ꡬν μ:
// SQLiteAueryBuilderλ μ μ ν SQL ꡬ문μ μμ±νλ κ²μ λμμ£Όλ ν΄λμ€ μ
λλ€.
SQLIteQueryBuilder qBuilder = new SQLiteQueryBuilder();
// μ°λ¦¬κ° 쿼리λ₯Ό μ§νν ν
μ΄λΈμ μ€μ ν©λλ€.
qBuilder.setTables(DATABASE_TABEL_NAME);
// λ§μ½ νΉμ λ μ½λ μ«μμμ μΏΌλ¦¬κ° λλλ€λ©΄, μ°λ¦¬λ νΉμ λ μ½λμ λν μμ²μ λ°μ κ²μ΄κ³ ,
// 쿼리 μμ WHERE μ μ μ€μ ν©λλ€.
if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE) {
qBuilder.appendWhere("_id=" + uri.getPathLeafId());
}
// 쿼리λ₯Ό λ§λ€μ΄ μ€λλ€.
Cursor c = qBuilde.query(mDb,
projection,
selection,
selectionArgs,
groupBy,
having,
sortOrder);
c.setNotificationUri(getCotext().getContentResolver(), uri);
return c;
insert
public Uri insert (Uri uri, ContentValues values, Bundle extras)
public abstract Uri insert(Uri uri,ConentValues values)
μλ‘μ΄ ν νλλ₯Ό μ½μ νλ μμ²μ μ²λ¦¬νλ €λ©΄ μ΄κ²μ ꡬννμΈμ. μλ‘μ μΌλ‘, μ½μ νμλ notifyChanged()λ₯Ό νΈμΆνμΈμ. Processes and Threadsμμ κΈ°μ λ λ°μ κ°μ΄, μ΄ λ©μλλ μ¬λ¬ μ°λ λμμ νΈμΆ κ°λ₯ν©λλ€.
update
public int update (Uri uri, ContentValues values, Bundel extras)
public int update (Uri uri, ContentValues values, String selection, String[] selectionArgs)
νλ μ΄μμ νλ€(rows)μ μ λ°μ΄νΈ νλ μμ²λ€μ μ²λ¦¬νλ €λ©΄ μ΄κ²μ ꡬννμΈμ. μ΄ κ΅¬νμ μ 곡λ κ°μμ mapμ λ°λΌ μ΄λ€(columns)μ μ€μ νκΈ° μν΄ μ ν(selection)κ³Ό μΌμΉνλ λͺ¨λ νλ€μ μ λ°μ΄νΈν΄μΌ ν©λλ€. μλ‘μ μΌλ‘, μ λ°μ΄νΈ νμλ notifyChange()λ₯Ό νΈμΆνμΈμ. Processes and Threadsμμ κΈ°μ λ λ°μ κ°μ΄, μ΄ λ©μλλ μ¬λ¬ μ°λ λμμ νΈμΆ κ°λ₯ν©λλ€.
delete
public abstract int delete (Uri uri, String selection, String[] selectionArgs)
public int delete (Uri uri, Bundel extra)
νλ μ΄μμ νλ€(rows)μ μμ νλ μμ²λ€μ μ²λ¦¬νλ €λ©΄ μ΄κ²μ ꡬννμΈμ. μ΄ κ΅¬νμ μμ μμ μ ν λμ μ ν μ‘°ν(selection clause)μ μ μ©ν΄ κ·Έ μμ μ΄ ν λλ ν°λ¦¬ μμμ μ¬λ¬ νλ€μ΄ μν₯μ μ£Όλλ‘ ν΄μΌ ν©λλ€. μλ‘μ μΌλ‘, μμ νμλ notifyChanged()λ₯Ό νΈμΆνμΈμ. Processes and Threadsμμ κΈ°μ λ λ°μ κ°μ΄, μ΄ λ©μλλ μ¬λ¬ μ°λ λμμ νΈμΆ κ°λ₯ν©λλ€.
μ΄ κ΅¬νμ νΉμ± νμ΄ μμ λλ κ²½μ°μ URI λμ ν IDλ₯Ό νμ±ν μ± μ μ΄ μμ΅λλ€. μ¦, ν΄λΌμ΄μΈνΈκ° contnet://contacts/people.22λ₯Ό 보λ΄κ³ ꡬνμ SQL ꡬ문μ μμ±ν λμ λ μ½λ μ«μ(22)λ₯Ό νμ±ν μ± μ μ΄ μμ£ .
getType
public abstract String getType (Uri uri)
μ£Όμ΄μ§ URIμμ λ°μ΄ν°μ MIME νμ μ λν μμ²μ μ²λ¦¬νλ €λ©΄ μ΄κ²μ ꡬννμΈμ. λ°νλ MIME νμ μ λ¨μΌ λ μ½λμ κ²½μ° vnd.android.cursor.itemμΌλ‘ μμνκ±°λ, μ¬λ¬ νλͺ©λ€μΈ κ²½μ°μ vnd.android.cursor.dir/λ‘ μμν΄μΌν©λλ€. μ΄ λ©μλλ Processes and Threads μμ κΈ°μ λ λλ‘, μ¬λ¬ μ°λ λμμ νΈμΆν μ μμ΅λλ€.
μ ν리μΌμ΄μ μ΄ μ΄ μ 보(MIME νμ )μ μ κ·Όνλλ° νμν κΆνμ μμ΅λλ€. λ§μ½ μ½ν μΈ νλ‘λ°μ΄λκ° μ½κΈ° κ·Έλ¦¬κ³ /λλ μ°κΈ° κΆνλ€μ΄ νμνκ±°λ, μ½ν μΈ νλ‘λ°μ΄λκ° exported λμ§ μλλ€λ©΄, λͺ¨λ μ ν리μΌμ΄μ λ€μ μ κ·Ό κΆνκ³Ό μκ΄μμ΄ μ΄ λ©μλλ₯Ό κ³μ νΈμΆν μ μμ΅λλ€. μ΄λ κ² μΈν νΈλ€μ΄ λ°μ‘λ λ URIμ MIME νμ μ κ²μν μ μμ΅λλ€.
'λΉ κ΅¬λ© μ±μ°κΈ°' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Android] ComponentCallbacks2 λ¬Έμ μ½κΈ° (0) | 2022.10.21 |
---|---|
[Android] ContentResolver λ¬Έμ μ½κΈ° (0) | 2022.10.14 |
[Android] κΈ°λ³Έ μ 곡 BindingAdapter (0) | 2022.10.13 |
[Android] ViewGroup.LayoutParams λ¬Έμ μ½κΈ° (0) | 2022.10.12 |
[Android] View λ¬Έμ μ½κΈ° (1) | 2022.10.07 |