2

我在我的應用程序中有一個內容提供商,我真的不喜歡它:-)。提供者是在閱讀了the official onethis unofficial one之類的文章之後創建的。更好的方式來創建Android內容提供商

我真的不喜歡的是提供程序類中的重複量(請參閱下面的非常精簡的代碼)。即使對於兩個(或四個,這取決於你如何計數)內容類型,也有太多的代碼。

我想過要去其他路線:在內容提供商的原始SQL查詢,但不知道這是否會變得更加優雅。

請指教一個更好的方式來創建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; 
    }  
    // .... 
} 
+0

你在說什麼重複?你能更具體一點,並強調代碼中的區域? – kpsfoo

回答

-1

使用不同的類來實現的ContentProvider和DatabaseHelper。看看例子完全不是你的例子有些不同,但你會看到它的想法。

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; 
} 

}

和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); 
    } 
} 
+0

謝謝你的回答,但你的代碼看起來非常像我的。也許我錯過了什麼? – Bobrovsky

+0

是啊,這是非常相同的,我只是說我已經看到了各種各樣的例子和Android模塊,他們都把DatabaseHelper和ContentProvider都放到了不同的類中,並且你在示例中已經將數據庫幫助器作爲內部類。也許你得到了我想說的話.. – Anonymous