领域提供商

时间:2017-04-19 03:22:18

标签: android realm android-contentprovider

所以,我已经习惯了Realm一段时间了。目前,我有一项任务是与我的其他应用程序共享登录数据。

由于使用Realm存储登录数据。我选择使用Content Provider。

我找到了一个例子:https://speakerdeck.com/androhi/realm-with-contentprovider

不幸的是,我无法让它发挥作用。这是 app A

中的内容提供商
static final String[] sColumns = new String[]{
        "LoginResultData"
};

public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
                    @Nullable String[] selectionArgs, @Nullable String sortOrder) {

    Realm mRealm = Realm.getDefaultInstance();

    RealmQuery<LoginResultData> query = mRealm.where(LoginResultData.class);
    LoginResultData result = query.findFirst();

    String json = new Gson().toJson(result);

    MatrixCursor matrixCursor = new MatrixCursor(sColumns);
    Object[] rowData = new Object[]{json};
    matrixCursor.addRow(rowData);

    return matrixCursor;
}

App B (需要获取登录数据)在我

时挂起
getContentResolver.query(uri, null, null, null, null);

我不知道为什么但是当我使用SQlite时效果很好。所以我假设Realm与Content Provider smh不兼容。这是真的吗?

如果没有,请向我展示使用Realm的Content Provider的示例。

谢谢!

1 个答案:

答案 0 :(得分:4)

Content Provider可与RealmDB配合使用。

您需要做的就是覆盖ContentProvider中的CRUD方法。请查看下面的内容提供程序类。需要注意的3件事:

  1. RealmDB在onCreate()方法中初始化 ContentProvider(不是应用程序活动)

  2. 您以适合RealmDB的方式覆盖CRUD方法(查询,插入,删除,更新)。检查以下样本。

  3. 这就是你需要做的。在其余代码中,您将使用本地组件,如recyclerview,adapter,loaders,services。您需要查询的任何地方,您将使用getContentResolver.query(uri,null,null,null,null)调用它;
  4. TaskProvider.java

    package com.example.rgher.realmtodo.data;
    
    import android.app.job.JobInfo;
    import android.app.job.JobScheduler;
    import android.content.ComponentName;
    import android.content.ContentProvider;
    import android.content.ContentUris;
    import android.content.ContentValues;
    import android.content.Context;
    import android.content.UriMatcher;
    import android.database.Cursor;
    import android.database.MatrixCursor;
    import android.net.Uri;
    import android.support.annotation.Nullable;
    import android.text.format.DateUtils;
    import android.util.Log;
    
    import io.realm.DynamicRealm;
    import io.realm.Realm;
    import io.realm.RealmConfiguration;
    import io.realm.RealmMigration;
    import io.realm.RealmResults;
    import io.realm.RealmSchema;
    
    import com.example.rgher.realmtodo.data.DatabaseContract.TaskColumns;
    
    public class TaskProvider extends ContentProvider {
        private static final String TAG = TaskProvider.class.getSimpleName();
    
        private static final int CLEANUP_JOB_ID = 43;
        private static final int TASKS = 100;
        private static final int TASKS_WITH_ID = 101;
    
        private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        static {
            // content://com.example.rgher.realmtodo/tasks
            sUriMatcher.addURI(DatabaseContract.CONTENT_AUTHORITY,
                    DatabaseContract.TABLE_TASKS,
                    TASKS);
    
            // content://com.example.rgher.realmtodo/tasks/id
            sUriMatcher.addURI(DatabaseContract.CONTENT_AUTHORITY,
                    DatabaseContract.TABLE_TASKS + "/#",
                    TASKS_WITH_ID);
        }
    
        @Override
        public boolean onCreate() {
    
            //Innitializing RealmDB
            Realm.init(getContext());
            RealmConfiguration config = new RealmConfiguration.Builder()
                    .schemaVersion(1)
                    .migration(new MyRealmMigration())
                    .build();
            Realm.setDefaultConfiguration(config);
    
            manageCleanupJob();
    
            return true;
        }
    
        @Nullable
        @Override
        public String getType(Uri uri) {
            return null; /* Not used */
        }
    
        @Nullable
        @Override
        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                            String sortOrder) {
    
            int match = sUriMatcher.match(uri);
    
            //Get Realm Instance
            Realm realm = Realm.getDefaultInstance();
            MatrixCursor myCursor = new MatrixCursor( new String[]{TaskColumns._ID, TaskColumns.DESCRIPTION
                    , TaskColumns.IS_COMPLETE, TaskColumns.IS_PRIORITY
                    , TaskColumns.DUE_DATE
            });
    
            try {
                switch (match) {
                    //Expected "query all" Uri: content://com.example.rgher.realmtodo/tasks
    
                    case TASKS:
                        RealmResults<RealmTask> tasksRealmResults = realm.where(RealmTask.class).findAll();
                        for (RealmTask myTask : tasksRealmResults) {
                            Object[] rowData = new Object[]{myTask.getTask_id(), myTask.getDescription(), myTask.getIs_complete()
                                    , myTask.getIs_priority(), myTask.getDue_date()};
                            myCursor.addRow(rowData);
                            Log.v("RealmDB", myTask.toString());
                        }
                        break;
    
                    //Expected "query one" Uri: content://com.example.rgher.realmtodo/tasks/{id}
                    case TASKS_WITH_ID:
                        Integer id = Integer.parseInt(uri.getPathSegments().get(1));
                        RealmTask myTask = realm.where(RealmTask.class).equalTo("task_id", id).findFirst();
                        myCursor.addRow(new Object[]{myTask.getTask_id(), myTask.getDescription(), myTask.getIs_complete(), myTask.getIs_priority(), myTask.getDue_date()});
                        Log.v("RealmDB", myTask.toString());
                        break;
                    default:
                        throw new UnsupportedOperationException("Unknown uri: " + uri);
                }
    
    
            myCursor.setNotificationUri(getContext().getContentResolver(), uri);
            } finally {
                realm.close();
            }
            return myCursor;
    
        }
    
        @Nullable
        @Override
        public Uri insert(Uri uri, final ContentValues contentValues) {
            //COMPLETE: Expected Uri: content://com.example.rgher.realmtodo/tasks
    
            //final SQLiteDatabase taskDb = mDbHelper.getReadableDatabase();
            int match = sUriMatcher.match(uri);
            Uri returnUri;
    
            //Get Realm Instance
            Realm realm = Realm.getDefaultInstance();
            try {
                switch (match) {
                    case TASKS:
                        realm.executeTransaction(new Realm.Transaction() {
                            @Override
                            public void execute(Realm realm) {
    
                                Number currId = realm.where(RealmTask.class).max(TaskColumns._ID);
                                Integer nextId = (currId == null) ? 1 : currId.intValue() + 1;
    
                                RealmTask myNewTask = realm.createObject(RealmTask.class, nextId);
                                myNewTask.setDescription(contentValues.get(TaskColumns.DESCRIPTION).toString());
                                myNewTask.setIs_complete((Integer) contentValues.get(TaskColumns.IS_COMPLETE));
                                myNewTask.setIs_priority((Integer) contentValues.get(TaskColumns.IS_PRIORITY));
                                myNewTask.setDue_date((Long) contentValues.get(TaskColumns.DUE_DATE));
                            }
                        });
                        returnUri = ContentUris.withAppendedId(DatabaseContract.CONTENT_URI, '1');
                        break;
    
                    default:
                        throw new UnsupportedOperationException("Unknown uri: " + uri);
                }
    
                getContext().getContentResolver().notifyChange(uri, null);
            }finally {
                realm.close();
            }
            return returnUri;
        }
    
        @Override
        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    
            //Expected Uri: content://com.example.rgher.realmtodo/tasks/{id}
            Realm realm = Realm.getDefaultInstance();
    
                int match = sUriMatcher.match(uri);
                int nrUpdated = 0;
            try {
                switch (match) {
                    case TASKS_WITH_ID:
                        Integer id = Integer.parseInt(uri.getPathSegments().get(1));
                        RealmTask myTask = realm.where(RealmTask.class).equalTo("task_id", id).findFirst();
                        realm.beginTransaction();
                        myTask.setIs_complete(Integer.parseInt(values.get(TaskColumns.IS_COMPLETE).toString()));
                        if (values.get(TaskColumns.DUE_DATE) != null) {
                            myTask.setDue_date(Long.valueOf(values.get(TaskColumns.DUE_DATE).toString()));
                        }
                        nrUpdated++;
                        realm.commitTransaction();
                        break;
                    default:
                        throw new UnsupportedOperationException("Unknown uri: " + uri);
                }
    
    
            } finally {
                realm.close();
            }
    
            if (nrUpdated != 0) {
                getContext().getContentResolver().notifyChange(uri, null);
            }
            return nrUpdated;
        }
    
        @Override
        public int delete(Uri uri, String selection, String[] selectionArgs) {
            int count = 0;
            Realm realm = Realm.getDefaultInstance();
            try {
                switch (sUriMatcher.match(uri)) {
                    case TASKS:
                        selection = (selection == null) ? "1" : selection;
                        RealmResults<RealmTask> tasksRealmResults = realm.where(RealmTask.class).equalTo(selection, Integer.parseInt(selectionArgs[0])).findAll();
                        realm.beginTransaction();
                        tasksRealmResults.deleteAllFromRealm();
                        count++;
                        realm.commitTransaction();
                        break;
                    case TASKS_WITH_ID:
                        Integer id = Integer.parseInt(String.valueOf(ContentUris.parseId(uri)));
                        RealmTask myTask = realm.where(RealmTask.class).equalTo("task_id", id).findFirst();
                        realm.beginTransaction();
                        myTask.deleteFromRealm();
                        count++;
                        realm.commitTransaction();
                        break;
                    default:
                        throw new IllegalArgumentException("Illegal delete URI");
                }
            } finally {
                realm.close();
            }
            if (count > 0) {
                //Notify observers of the change
                getContext().getContentResolver().notifyChange(uri, null);
            }
    
            return count;
        }
    
    }
    
    // Example of REALM migration
    class MyRealmMigration implements RealmMigration {
        @Override
        public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
    
            RealmSchema schema = realm.getSchema();
    
            if (oldVersion != 0) {
                schema.create(DatabaseContract.TABLE_TASKS)
                        .addField(DatabaseContract.TaskColumns._ID, Integer.class)
                        .addField(DatabaseContract.TaskColumns.DESCRIPTION, String.class)
                        .addField(DatabaseContract.TaskColumns.IS_COMPLETE, Integer.class)
                        .addField(DatabaseContract.TaskColumns.IS_PRIORITY, Integer.class);
                oldVersion++;
            }
    
        }
    }
    

    您可以在此处找到完整的应用程序 https://github.com/rgherta/RealmTodo

    祝你好运