12

私はドキュメントを読んでいましたが、それでもよくわかりません。を使用するように指示さgetContentResolver()れていますが、実際にはCursorLoaderを使用していません。それで、それを実行する方法はありCursorLoaderますか?私はでそれを行う方法を知っていますquery()。手順は非常に似ていますか?これを正確に説明するリンクだけでも役に立ちます。

insert()を使用してContentProviderのメソッドを使用する例がないため、GoogleドキュメントにリンクしないでくださいCursorLoader

前もって感謝します!!

編集:私がこれと混同している理由は、newを呼び出すとCursorLoader自動的にContentProviders query()メソッドが呼び出されるためです。しかし、どうすれば挿入に対して同じことができますか?

4

2 に答える 2

40

このテーマに関する私のブログ投稿をチェックしてください:

コンテンツリゾルバーとコンテンツプロバイダー


はそれCursorLoaderとは何の関係もありません。

挿入はまったく異なる概念です...それは。とはまったく関係がありませCursorLoader。と組み合わせると、データベースLoaderManagerCursorLoader自動的にクエリを実行しContentObserver、データストアの変更が通知されると自動的に更新されます。データベースにデータを挿入する実際のプロセスとは何の関係もありません。

へのリクエストのContentResolver解決方法

コンテンツプロバイダーを介してデータベースにデータを挿入(またはクエリまたは更新または削除)する場合、プロバイダーと直接通信することはありません。代わりに、ContentResolverオブジェクトを使用してプロバイダーと通信します(ContentResolverは、アプリケーションのグローバル内のプライベートインスタンス変数であることに注意してくださいContext)。より具体的には、実行される一連のステップは次のとおりです。

  1. あなたが呼ぶgetContentResolver().insert(Uri, ContentValues);

  2. ContentResolverオブジェクトは、Uriの権限を決定します。

  3. リレーはContentResolver、権限に登録されているコンテンツプロバイダーに要求を中継します(これが、で権限を指定する必要がある理由ですAndroidManifest.xml)。

  4. コンテンツプロバイダーはリクエストを受信し、指定された操作(この場合insert)を実行します。データが挿入される方法と場所は、メソッドの実装方法によって異なります(insertは、ユーザーが、、、、、およびをContentProvider実装する必要がある抽象クラスです)。insertquerydeleteupdategetType

うまくいけば、少なくとも少しは頭を包むことができたでしょう。多くの手順が必要になる理由は、Androidが(1)アプリケーションに複数のコンテンツプロバイダーを許可し、(2)アプリが他のサードパーティアプリとデータを安全に共有できるようにする必要があるためです。(それはあなたを混乱させたかったからではありませんでした、私は約束します)。

経由でデータを挿入するContentProvider

これで、(うまくいけば)ContentResolverこれらの要求をコンテンツプロバイダーに中継する方法についてより良いアイデアが得られたので、データの挿入はかなり簡単です。

  1. まず、コンテンツプロバイダーが一致させたいURIを決定します。これは、urisを。と一致させることにした方法によって異なりますUriMatcher。使用している各URIは、内部データベースにデータを挿入するためのさまざまな手段を表しています(つまり、アプリに2つのテーブルがある場合、各テーブルに1つずつ、合計2つのURIがあります)。

  2. 新しいContentValuesオブジェクトを作成し、それを使用して、コンテンツプロバイダーに送信するデータをパッケージ化します。オブジェクトは、ContentValues列名をデータ値にマップします。次の例では、列名は「column_1」であり、その列の下に挿入される値は「value_1」です。

    ContentValues values = new ContentValues();
    values.put("column_1", "value_1");
    
  3. 受信すると、コンテンツプロバイダーは(あなたの場合)valuesオブジェクトをSQLiteDatabase(メソッドを介してSQLiteDatabase.insert(String table, String nullColumnHack, ContentValues values))あなたに渡します。とは異なりContentProvider、このメソッドは実装されています...オブジェクトSQLiteDatabaseの処理方法を知ってvaluesおり、データベースに行を挿入し、挿入された行の行IDを返す-1か、挿入が失敗した場合に返します。

...そしてそれがあなたのデータベースにデータを挿入する方法です。


TL; DR

使用するgetContentResolver().insert(Uri, ContentValues);

于 2012-06-21T04:04:59.983 に答える
2

データベースを簡単に挿入できるように、カーソルをContentValuesに変換します。

getContentResolver()を使用するように指示されていますが、実際にはCursorLoaderを使用していません

Alexが言ったこと以外に、Cursor返されたものを繰り返し処理し、それらをContentValuesに入れてから、それを(たとえば、別のDBに)挿入することを妨げるものは何もありません。

私の頭のてっぺんからのほんの一例(Cursor2String列の単純なもの):

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    if (cursor.moveToFirst()) {
        ArrayList<ContentValues> values = new ArrayList<ContentValues>();
        do {
            ContentValues row = new ContentValues();
            DatabaseUtils.cursorStringToContentValues(cursor, fieldFirstName, row);
            DatabaseUtils.cursorStringToContentValues(cursor, fieldLastName, row);
            values.add(row);
        } while (cursor.moveToNext());
        ContentValues[] cv = new ContentValues[values.size()];
        values.toArray(cv);
        getContentResolver().bulkInsert(CONTENT_NAMES, cv);
    }
}

それを行うにはおそらくもっと効率的な方法があります(そして間違いなくいくつかの整合性チェック)が、それが私の最初の考えでした...

于 2012-06-21T04:20:13.923 に答える