Android ContentProvider 자세히 알아보기
Cursor query(Uri, ....) {
if (uri is for vCard) {
query the Contact's infomation
create a cursor with two columns name and size
put contact's name into cursor
sum all Contact's field and get size
put that size into cursor
return the cursor
}
}
이렇게 하면 Query를 통해 이 vCard와 관련된 정보 파일의 이름과 크기를 얻을 수 있고 OpenInputStream을 통해 이 vCard 파일 흐름을 읽을 수 있다. 그러나 실제로 ContentProvider는 vCard 형식의 데이터도 없고 vCard 파일도 하나도 없다. 이것은 OpenFile을 할 때 vCard의uri를 식별하고 Contact 데이터를 vCard 형식으로 바꾸어 출력 흐름에 쓴다
ParcelFileDescriptor openFile(Uri...) {
if (uri is for vcard) {
generate vcard with VCardComposer
write to output stream
}
}
3. 다른 대체 방안인 ContentProvider는 필수가 아닙니다. 모든 응용 프로그램은 반드시 데이터에 사용되지만 ContentProvider를 만들어서 관리할 수도 있고 파일이나 데이터베이스를 직접 사용할 수도 있습니다. 예를 들어 다음과 같습니다
package com.android.effective;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.os.Bundle;
import android.util.Log;
public class SQLiteDatabaseDemo extends Activity {
private static final String TAG = "SQLiteDatabaseDemo";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyDatabase db = new MyDatabase(this);
int id = db.setName("Michael Jordan");
Log.e(TAG, "id of " + id + " is " + db.getName(id));
}
private class MyDatabase {
private static final String name = "demo.db";
private static final String table = "demo";
private final String[] projection = new String[] {"_id", "name" };
private MyDatabaseHelper helper;
public MyDatabase(Context context) {
helper = new MyDatabaseHelper(context, name, null, 1);
}
public String getName(int id) {
final Cursor c = helper.getReadableDatabase().query("demo", projection, "_id=" + id,
null, null, null, null);
if (c == null || !c.moveToFirst()) {
return null;
}
return c.getString(1);
}
public int setName(String name) {
ContentValues cv = new ContentValues();
cv.put("name", name);
return (int) helper.getWritableDatabase().insert(table, "name", cv);
}
}
private class MyDatabaseHelper extends SQLiteOpenHelper {
public MyDatabaseHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE demo (_id INTEGER PRIMARY KEY, name TEXT);");
}
@Override
public void onUpgrade(SQLiteDatabase db, int old, int newver) {
}
}
}
이 예에서 ContentProvider를 사용하지 않고 Activity가 SQLiteDatabase를 직접 조작하여 데이터의 관리를 실현하거나 데이터베이스를 사용하지 않고 파일을 사용하여 데이터를 관리한다.이런 방식은 실현하기에 더욱 간단할 수 있다. 수요가 크지 않고 데이터의 양이 크지 않으며 단일 구성 요소만 사용하는 상황에서 이런 방식을 충분히 사용할 수 있다.그러나 그 단점도 뚜렷하다. 바로 구성 요소 사이에서 전달하는 것이 매우 번거롭고 심지어는 구성 요소 사이에서 공유할 수 없다는 것이다.공유를 위해서는 데이터 층을 추상적으로 하고 그 어떠한 활동에도 독립시켜 서로 다른 구성 요소가 데이터에 대해 읽기와 쓰기를 만족시켜야 한다. 그러나 이렇게 하면 하나의 ContentProvider를 실현하는 것과 차이가 없고 차라리 하나의 ContentProvider를 실현하는 것이 편리하다.따라서 규칙은 만약에 어떤 데이터가 하나의 Activity에서만 사용된다면 ContentProvider를 만들 필요가 없고 파일을 직접 사용하거나 Database를 직접 조작하면 목적을 달성할 수 있다는 것이다.그러나 다른 구성 요소와 데이터를 공유하고 전달해야 한다면 ContentProvider를 사용해야 한다.또한 ContentProvider가 있으면 다른 응용 프로그램과 상호작용을 하고 데이터를 다른 응용 프로그램의 구성 요소에 전달할 수 있다.SQLiteOpenHelper를 사용할 때 반드시 스레드 동기화 문제를 주의하고 모든 SQLiteDatabase 방법(예를 들어 execSQL)의 스레드 안전성을 확보해야 한다. 그렇지 않으면 매우 보기 드문 이상을 일으킬 수 있다.SQLiteStatement에서 보고한 NPE(Null Pointer Exception)를 만났습니다. 여러 개의 스레드가 같은 SQLite OpenHelper를 조작하고 동기화되지 않았기 때문입니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Android Webkit 요약(개요에서 최신 AndroidX까지)WebView는 Android 응용 프로그램에서 HTML과 웹 페이지 등 HTML 파일을 렌더링(표시)하는 기능을 제공하는 View입니다. Android Webkit은 실제 WebView의 핵심 기술인 렌더링 엔진(...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.