简体   繁体   English

创建Android内容提供商的更好方法

[英]Better way to create Android content providers

I have a content provider in my app and I really don't like it :-). 我的应用程序中有一个内容提供商,但我真的不喜欢它:-)。 The provider is created after reading number of articles like the official one and this unofficial one . 提供者是在阅读了一些官方文章和非官方文章之后创建的。

What I really don't like is the amount of duplication in the provider class (see very stripped down code below). 我真正不喜欢的是提供程序类中的重复次数(请参阅下面的精简代码)。 Even for two (or four, it depends on how you count) content types there is too much code. 即使对于两种(或四种,取决于您的计数方式)内容类型,代码也太多了。

I thought about going the other route: raw SQL queries in the content provider but not sure if this will turn out to be more elegant. 我考虑过要走另一条路:在内容提供程序中使用原始SQL查询,但不确定是否会更优雅。

Please advise a better way to create Android content providers then the one in the code below. 请提供比下面代码中的方法更好的创建Android内容提供商的方法。

public abstract class BaseProvider extends ContentProvider
{
    protected DatabaseHelper m_helper;

    protected static class DatabaseHelper extends SQLiteOpenHelper
    {
        private static final String DATABASE_NAME = "my.db";
        private static final int DATABASE_VERSION = 4;

        public DatabaseHelper(Context context)
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db)
        {
            FolderTable.onCreate(db);
            TrackTable.onCreate(db);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
        {
            FolderTable.onUpgrade(db, oldVersion, newVersion);
            TrackTable.onUpgrade(db, oldVersion, newVersion);
        }
    }

    @Override
    public boolean onCreate()
    {
        m_helper = new DatabaseHelper(getContext());
        return true;
    }
    // ...
}


public class MyProvider extends BaseProvider
{    
    private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    private static final int FOLDERS = 10;
    private static final int FOLDER_ID = 20;
    private static final int TRACKS = 30;
    private static final int TRACK_ID = 40;

    private static final String FOLDERS_BASE_PATH = "folders";
    private static final String TRACKS_BASE_PATH = "tracks";

    public static final String AUTHORITY = ".contentprovider.MyProvider";
    private static final String CONTENT_URI_BASE = "content://" + AUTHORITY + "/";

    public static final Uri FOLDERS_CONTENT_URI = Uri.parse(CONTENT_URI_BASE + FOLDERS_BASE_PATH);
    public static final Uri TRACKS_CONTENT_URI = Uri.parse(CONTENT_URI_BASE + TRACKS_BASE_PATH);

    static
    {
        sURIMatcher.addURI(AUTHORITY, FOLDERS_BASE_PATH, FOLDERS);
        sURIMatcher.addURI(AUTHORITY, FOLDERS_BASE_PATH + "/#", FOLDER_ID);
        sURIMatcher.addURI(AUTHORITY, TRACKS_BASE_PATH, TRACKS);
        sURIMatcher.addURI(AUTHORITY, TRACKS_BASE_PATH + "/#", TRACK_ID);
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder)
    {
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();

        int uriType = sURIMatcher.match(uri);
        switch (uriType)
        {
            case FOLDERS:
                queryBuilder.setTables(getTablesForFolders());
                break;

            case FOLDER_ID:
                queryBuilder.setTables(FolderTable.TABLE_NAME);
                queryBuilder.appendWhere(FolderTable.COLUMN_ID + "=" + uri.getLastPathSegment());
                break;

            case TRACKS:
                queryBuilder.setTables(getTablesForTracks());
                break;

            case TRACK_ID:
                queryBuilder.setTables(TrackTable.TABLE_NAME);
                queryBuilder.appendWhere(TrackTable.COLUMN_ID + "=" + uri.getLastPathSegment());
                break;

        default:
                throw new IllegalArgumentException("Unknown URI: " + uri);
        }

        SQLiteDatabase db = m_helper.getWritableDatabase();
        if (db == null)
            return null;

        Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
        if (cursor == null)
            return null;

        setNotificationUri(cursor, uri);

        return cursor;
    }    
    // ....
}

Use different class to implement ContentProvider and DatabaseHelper. 使用不同的类来实现ContentProvider和DatabaseHelper。 See example exactly not your's example something different but you will get idea by seeing it. 看到的示例与您的示例完全不同,但是您会通过看到它而获得想法。

DatabaseHelper.java DatabaseHelper.java

public class DatabaseHelper extends SQLiteOpenHelper{

private static final String name="mybooks.sdb";
private static final int version=1;
private static final CursorFactory factory=null;
public DatabaseHelper(Context context)
{
    super(context,name,factory,version);
}
@Override
public void onCreate(SQLiteDatabase database) {
    // TODO Auto-generated method stub
    database.execSQL("create table mybooks(code INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT,author TEXT)");
}

@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
    // TODO Auto-generated method stub

}
public long insert(ContentValues contentValues)
{
    long x;
    SQLiteDatabase database=this.getWritableDatabase();
    x=database.insert("mybooks",null, contentValues);
    database.close();
    return x;
}
public Cursor query(String[] columns,String whereClause,String[] replaceQuestionMarksWith,String orderBy)
{
    SQLiteDatabase database=this.getReadableDatabase();
    return database.query("mybooks", columns, whereClause, replaceQuestionMarksWith, null, null, orderBy);
}
public int update(ContentValues contentValues,String whereClause,String[] replaceQuestionMarksWith)
{
    SQLiteDatabase database=this.getWritableDatabase();
    int numberOfRecordsUpdated=database.update("mybooks", contentValues, whereClause, replaceQuestionMarksWith);
    database.close();
    return numberOfRecordsUpdated;
}
public int delete(String whereClause,String[] replaceQuestionMarksWith)
{
    SQLiteDatabase database=this.getWritableDatabase();
    int numberOfRecordsDeleted=database.delete("mybooks", whereClause, replaceQuestionMarksWith);
    database.close();
    return numberOfRecordsDeleted;
}

} }

and ContentProvider.java as 和ContentProvider.java作为

    public class MyBookProvider extends ContentProvider{
    private DatabaseHelper databaseHelper;
    private static final UriMatcher uriMatcher;
    private static final int INCOMING_BOOK_COLLECTION_URI_INDICATOR = 1;
    private static final int INCOMING_ONE_BOOK_URI_INDICATOR = 2;

    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);               
        uriMatcher.addURI(LibraryContentProviderMetaData.AUTHORITY, "books",INCOMING_BOOK_COLLECTION_URI_INDICATOR);        
        uriMatcher.addURI(LibraryContentProviderMetaData.AUTHORITY, "books/#",INCOMING_ONE_BOOK_URI_INDICATOR); 
    }
@Override
    public String getType(Uri uri) 
    {
        String mimeType;
        switch(uriMatcher.match(uri))
        {
            case INCOMING_BOOK_COLLECTION_URI_INDICATOR:
                mimeType=LibraryContentProviderMetaData.CONTENT_TYPE;
                break;
            case INCOMING_ONE_BOOK_URI_INDICATOR:
                mimeType=LibraryContentProviderMetaData.CONTENT_ITEM_TYPE;
                break;
            default:throw new IllegalArgumentException("Invalid URI"+uri);
        }
        return mimeType;
    }
@Override
    public Uri insert(Uri uri, ContentValues contentValues) {
        // TODO Auto-generated method stub
        if (uriMatcher.match(uri) != INCOMING_BOOK_COLLECTION_URI_INDICATOR) 
        {
            throw new IllegalArgumentException("Invalid URI " + uri);
        }
        long x = databaseHelper.insert(contentValues);
        return Uri.parse("content//com.lib.mybooks.MyBookProvider/books/" + x);
    }
    @Override
    public boolean onCreate() {     
        databaseHelper = new DatabaseHelper(getContext());
        return true;
    }
    @Override
    public Cursor query(Uri uri, String[] columns, String whereClause,String[] replaceQuestionMarksWith, String orderBy) 
    {
        switch (uriMatcher.match(uri)) 
        {
        case INCOMING_BOOK_COLLECTION_URI_INDICATOR:break;
        case INCOMING_ONE_BOOK_URI_INDICATOR:whereClause = "code=?";
            replaceQuestionMarksWith = new String[] { uri.getPathSegments().get(1) };
            break;
        default:throw new IllegalArgumentException("Invalid URI " + uri);
        }
        Cursor cursor = databaseHelper.query(columns, whereClause,replaceQuestionMarksWith, orderBy);
        return cursor;
    }
    @Override
    public int update(Uri uri, ContentValues contentValues, String whereClause, String[] replaceQuestionMarksWith) 
    {
        if(uriMatcher.match(uri)!=INCOMING_BOOK_COLLECTION_URI_INDICATOR)
        {
            throw new IllegalArgumentException("Invalid URI "+uri);
        }

        return databaseHelper.update(contentValues, whereClause,replaceQuestionMarksWith);
    }
    @Override
    public int delete(Uri uri, String whereClause, String[] replaceQuestionMarksWith) 
    {
        if(uriMatcher.match(uri)!=INCOMING_BOOK_COLLECTION_URI_INDICATOR)
        {
            throw new IllegalArgumentException("Invalid URI "+uri);
        }
        return databaseHelper.delete(whereClause, replaceQuestionMarksWith);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM