Ich fand eine Lösung mit Unterklassen von ContentProvider. Nehmen wir an, Sie haben Tabelle tblA und eine andere Tabelle tblB. Ich empfehle zwei Klassen "AContentProvider" und "BContentProvider" zu erstellen. Stellen Sie vor allem sicher, dass beide Tabellen in derselben Datenbank eingerichtet sind.
Der Hauptteil der Lösung ist ContentProvider.query() in dem Contentprovider außer Kraft zu setzen, die Sie von Ihrem CursorLoader nennen - die URI entscheidet, welches es ist:
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sort) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(
"tblA LEFT JOIN tblB"
+ " ON ("
+ "tblA.b_id"
+ " = "
+ "tblB.id"
+ ")"
);
...
// Content of projection is set by CursorLoader
// usually in an Activity that implements LoaderManager.LoaderCallbacks<>
Cursor c = qb.query(
database,
projection,
selection,
selectionArgs,
groupBy,
having,
orderBy
);
...
return c;
}
Wie Sie, die sehen JOIN erfolgt in SetTables().Mit Projektion Sie sicherstellen, dass Sie nur die Spalten angezeigt werden Sie wirklich brauchen, und vor allem, haben Sie keine doppelten Spalten, wie „id“ aus beiden Tabellen:
final String[] projection = new String[] {
"tblA.*",
"tblB.columnThatOnlyBHas"
};
Nutzen Sie die Überschreibung und versuchen, In den Unterklassen so viel Arbeit wie möglich erledigen; zum Beispiel: alle meine überschriebene query() Methoden setNotificationUri() aufrufen, die ContentResolver zu benachrichtigen, wenn die Cursor-Ergebnismenge ändert .:
c.setNotificationUri(getContext().getContentResolver(), uri);
ich Ihre Antwort oben, aber in meinem Fall Sinn der Verwendung von Join lesen ist Spalten abrufen aus mehreren verknüpften Tabellen mit nur einer Abfrage. Innerhalb eines einzelnen Cursors, den ich vom Cursor Loader bekomme, brauche ich DISPLAY_NAME_PRIMARY aus der ContactsContract.Contact Tabelle, ACCOUNT_NAME aus der ContactsContract.RawContact Tabelle und DATA1 aus der ContactsContract.DATA Tabelle. Nun verstehe ich nicht, wie einzelne Uri mir dabei helfen können, denn wenn ich Uri gebe Auf die ContactsContract.RawContact-Tabelle zeigend, wie werde ich dann auf verwandte Spalten von ContactsContract.Contact und ContactsContract.Data zugreifen? –
@AbhishekChauhan: Nun, in Ihrem Fall haben Sie den 'ContentProvider' nicht geschrieben, was bedeutet, dass Sie nicht" abhacken "können irgendwie mit rawSql Inside Content Provider ", wie du in deiner Frage behauptet hast. Meine Antwort richtet sich an jemanden, der den 'ContentProvider' schreibt und somit den Join in ihm machen kann. In Ihrem Fall müssen Sie Ihre Daten manuell von mehreren 'Cursor'-Objekten" verbinden ", und das' Loader'-Framework wird in diesem Bereich nicht viel helfen. Aus dem Stegreif, würde ich eine 'AsyncTask' verwenden, dann Abfragen mit' ContentResolver' durchführen und Ihre Daten in 'doInBackground()' zusammenführen, denke ich. – CommonsWare
ya ... danke, ich werde asynctask dafür verwenden und später zusammenführen ... dieser wird mir besser passen –