- <?xml
version="1.0" encoding="utf-8"?> - <manifest
xmlns:android="http://schemas.android.com/apk/res/android" -
package="com.misoo.SQ03"> -
<uses-permission xmlns:android="http://schemas.android.com/apk/res/android" -
android:name="android.permission.INTERNET"> -
</uses-permission> -
<application android:icon="@drawable/icon" android:label="@string/app_name"> -
<provider android:name="DataProvider" -
android:authorities="com.misoo.provider.SQ03"> -
</provider> -
<activity android:name=".ac01" android:label="@string/app_name"> -
<intent-filter> -
<action android:name="android.intent.action.MAIN" /> -
<category android:name="android.intent.category.LAUNCHER" /> -
</intent-filter> -
</activity> -
<activity android:name=".DispActivity" android:label="DispActivity"> -
</activity> -
</application> - </manifest>
这让Android知道我们城市里定义了多少个嫡系组件类别;Android可以在启动时就将它们执行起来,成为共享的(Shared)服务组件。这些嫡系服务组件间的沟通,通常是透过「意图」(Intent)对象来请Android转达给对方,Android则会依据意图而找出最佳的配对。配对成功,就展开相互的沟通与服务了。
2. 什么是ContentProvider嫡系组件
---- 以SQLite为例
2.1
- package
com.misoo.pklx; - import
java.util.ArrayList; - import
java.util.HashMap; - import
java.util.Map; - import
android.app.ListActivity; - import
android.database.Cursor; - import
android.os.Bundle; - import
android.view.View; - import
android.widget.ListView; - import
android.widget.SimpleAdapter; -
- public
class ac01 extends ListActivity { -
private static final String[] PROJECTION = new String[] { "stud_no", "stud_name" }; -
-
@Override protected void onCreate(Bundle savedInstanceState) { -
super.onCreate(savedInstanceState); -
DataProvider dp = new DataProvider(this); -
Cursor cur = dp.query(PROJECTION, null, null, null); -
ArrayList<Map<String, Object>> coll -
= new ArrayList<Map<String, Object>>(); -
Map<String, Object> item; -
cur.moveToFirst(); -
while(!cur.isAfterLast()) { -
item = new HashMap<String, Object>(); -
item.put("c1", cur.getString(0) + ", " + cur.getString(1)); -
coll.add(item); -
cur.moveToNext(); -
} -
dp.close(); -
this.setListAdapter(new SimpleAdapter(this, coll, -
android.R.layout.simple_list_item_1, new String[] { "c1" }, -
new int[] {android.R.id.text1})); -
} -
@Override -
protected void onListItemClick(ListView l, View v, int position, long id) { -
finish(); -
}}
这要求SQLite从数据库查询出某些数据。详细的DataProvider.java程序代码如下:
- package
com.misoo.pklx; - import
android.content.Context; - import
android.database.Cursor; - import
android.database.SQLException; - import
android.database.sqlite.SQLiteDatabase; - import
android.util.Log; -
- public
class DataProvider { -
private static final String DATABASE_NAME = "StudDB"; -
private static final String TABLE_NAME = "Student"; -
private final int DB_MODE = Context.MODE_PRIVATE; -
private SQLiteDatabase db=null; -
-
public DataProvider(Context ctx) { -
try { db = ctx.openOrCreateDatabase(DATABASE_NAME, DB_MODE, null); } - catch
(Exception e) { Log.e("ERROR", e.toString()); return; } -
-
try { db.execSQL("drop table "+ TABLE_NAME); } - catch
(Exception e) { Log.e("ERROR", e.toString()); } -
-
db.execSQL("CREATE TABLE " + TABLE_NAME + " (" + "stud_no" + " TEXT," -
+ "stud_name" + " TEXT" + ");"); -
String sql_1 = "insert into "+ TABLE_NAME + - "
(stud_no, stud_name) values('S101', 'Lily');"; -
String sql_2 = "insert into " + TABLE_NAME + - "
(stud_no, stud_name) values('S102', 'Linda');"; -
String sql_3 = "insert into " + TABLE_NAME + - "
(stud_no, stud_name) values('S103', 'Bruce');"; -
-
try { db.execSQL(sql_1); db.execSQL(sql_2); db.execSQL(sql_3); } -
catch (SQLException e) { Log.e("ERROR", e.toString()); return; } -
} -
public Cursor query(String[] projection, String selection, String[] selectionArgs, -
String sortOrder) { -
Cursor cur = db.query(TABLE_NAME, projection, null, null, null, null, null); -
return cur; -
} -
public void close(){ db.close(); } - }
这种用法属于非嫡系的用法:在ac01.java程序代码里,其指令:
明确指定由DataProvider对象来提供服务。反之,嫡系用法则是透过意图(Intent)来请Android代为配对,进而找出适当的ContentProvider对象来为aco1对象提供服务。
2.2
- package
com.misoo.pkrr; - import
java.util.ArrayList; - import
java.util.HashMap; - import
java.util.Map; - import
android.app.ListActivity; - import
android.content.Intent; - import
android.database.Cursor; - import
android.net.Uri; - import
android.os.Bundle; - import
android.view.View; - import
android.widget.ListView; - import
android.widget.SimpleAdapter; -
- public
class ac01 extends ListActivity { -
public static int g_variable; -
public static final String AUTHORITY = "com.misoo.provider.rx09-02"; -
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY -
+ "/Student"); -
private static final String[] PROJECTION -
= new String[]{ "stud_no", "stud_name"}; -
@Override protected void onCreate(Bundle savedInstanceState) { -
super.onCreate(savedInstanceState); -
Intent intent = getIntent(); -
if (intent.getData() == null) intent.setData(CONTENT_URI); -
Cursor cur = getContentResolver().query(getIntent().getData(), -
PROJECTION, null, null, null); -
ArrayList<Map<String, Object>> coll = new ArrayList<Map<String, Object>>(); -
Map<String, Object> item; -
cur.moveToFirst(); -
while (!cur.isAfterLast()) { -
item = new HashMap<String, Object>(); -
item.put("c1", cur.getString(0) + ", " + cur.getString(1)); -
coll.add(item); -
cur.moveToNext(); -
} -
this.setListAdapter(new SimpleAdapter(this, coll, -
android.R.layout.simple_list_item_1, new String[] { "c1" }, -
new int[] { android.R.id.text1 })); -
} -
@Override -
protected void onListItemClick(ListView l, View v, int position, long id) { finish();} - }
指令:
要求Android代为寻找适合的ContentProvider来提供服务,并不刻意指定由DataProvider对象来担任。只要合乎ConentProvider接口,且符合意图条件的对象皆可以来为ac01对象提供服务。于是,ac01程序代码就不再直接呼叫DataProvider类别的函数了,而是呼叫ContentProvider接口所提供的函数。再来仔细看看DataProvider类别与ContentProvider接口的搭配情形:
- package
com.misoo.pkrr; - import
android.content.ContentProvider; - import
android.content.ContentValues; - import
android.content.Context; - import
android.database.Cursor; - import
android.database.SQLException; - import
android.database.sqlite.SQLiteDatabase; - import
android.database.sqlite.SQLiteOpenHelper; - import
android.net.Uri; - import
android.util.Log; -
- public
class DataProvider extends ContentProvider { -
private static final String DATABASE_NAME = "StudNewDB"; -
private static final int DATABASE_VERSION = 2; -
private static final String TABLE_NAME = "StudTable"; -
private static class DatabaseHelper extends SQLiteOpenHelper { -
DatabaseHelper(Context context) { -
super(context, DATABASE_NAME, null, DATABASE_VERSION); } -
@Override public void onCreate(SQLiteDatabase db) { -
db.execSQL("CREATE TABLE " + TABLE_NAME + " (" + "stud_no" -
+ " TEXT," + "stud_name" + " TEXT" + ");"); -
String sql_1 = "insert into " + TABLE_NAME -
+ " (stud_no, stud_name) values('S1001', 'Pam');"; -
String sql_2 = "insert into " + TABLE_NAME -
+ " (stud_no, stud_name) values('S1002', 'Steve');"; -
String sql_3 = "insert into " + TABLE_NAME -
+ " (stud_no, stud_name) values('S1003', 'John');"; -
try { db.execSQL(sql_1); db.execSQL(sql_2); db.execSQL(sql_3); } -
catch (SQLException e) { Log.e("ERROR", e.toString()); } -
} -
@Override -
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {} -
} -
// --------------------------------------------------------------------------------- -
private DatabaseHelper mOpenHelper; -
@Override public boolean onCreate() { -
mOpenHelper = new DatabaseHelper(getContext()); return true; } -
@Override public Cursor query(Uri uri, String[] projection, String selection, -
String[] selectionArgs, String sortOrder) { -
SQLiteDatabase db = mOpenHelper.getReadableDatabase(); -
Cursor c = db.query(TABLE_NAME, projection, null, null, null, null, null); -
return c; -
} -
@Override public String getType(Uri uri) { return null; } -
@Override public Uri insert(Uri uri, ContentValues initialValues) { return uri; } -
@Override public int delete(Uri uri, String where, String[] whereArgs) { return 0; } -
@Override public int update(Uri uri, ContentValues values, String where, -
String[] whereArgs) - {
return 0; } - }
类别定义:
// …..…..
}
DataProvider类别继承ContentProvider父类别,也继承了它的接口定义。ContentProvider接口定义了多个函数,主要包括:
l
l
l
l
- <?xml
version="1.0" encoding="utf-8"?> - <manifest
xmlns:android="http://schemas.android.com/apk/res/android" -
package="com.misoo.pkrr" -
android:versionCode="1" -
android:versionName="1.0.0"> -
<application android:icon="@drawable/icon" android:label="@string/app_name"> -
<activity android:name=".ac01" -
android:label="@string/app_name"> -
<intent-filter> -
<action android:name="android.intent.action.MAIN" /> -
<category android:name="android.intent.category.LAUNCHER" /> -
</intent-filter> -
</activity> -
<provider android:name="DataProvider" -
android:authorities="com.misoo.provider.rx09-02"> -
</provider> -
</application> - </manifest>
这特别说明DataProvider是一个ContentProvider,于是Android就会来启动它。
转至:http://dev.10086.cn/cmdn/wiki/index.php?edition-view-2609-2.html