




下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、2.高焕堂讲解ContentProvider范例1.何谓Android的嫡系组件Android有4项一等公民(或称为嫡系亲属),包括:Activity、ContentProvider、IntentReceiver与Serviceo它们都必须宣告于AndroidManifest.xml档案里,如下:<?xmlversion="1.0"encoding="utf-8"?><manifestxmlns:android="package="com.misoo.SQ03"><uses-permission
2、xmlns:android="</uses-permission><applicationandroid:icon="drawable/icon"android:label="string/app_name"><providerandroid:name="DataProvider"android:authorities="vider.SQ03"></provider><activityandroid:name=".a
3、c01"android:label="string/app_name"><intent-filter><actionandroid:name="ent.action.MAIN"/><categoryandroid:name="ent.category.LAUNCHER"/></intent-filter></activity><activityandroid:name=".DispActivity&q
4、uot;android:label="DispActivity"></activity></application></manifest>这让Android知道我们城市里定义了多少个嫡系组件类别;Android可以在启动时就将它们执行起来,成为共享的(Shared)服务组件。这些嫡系服务组件间的沟通,通常是透过意图(Intent)对象来请Android转达给对方,Android则会依据意图而找出最佳的配对。配对成功,就展开相互的沟通与服务了。2. 什么是ContentProvider嫡系组件-以SQLite为例在Android里,S
5、QLite数据库是最典型的ContentProvider,负责储存各式各样的内容。除了数据库之外,还有许多其它种类的ContentProvidero在这里并不是要介绍这些ContentProvider,而是要透过SQLite认识ContentProvider接口,然后将舶来Linter组件,配上这种ContentProvider接口,让它摇身一变成为Android的嫡索组件。2.1 一月(即非嫡系)SQLite的范例没有透过ContentProvider接口来使用SQLite,就是对SQLite的非嫡系用法。此时,应用程序透过JDBC接口和SQL语句来与SQLite沟通,以存取数据库里的内容。
6、先认识这种传统用法。此范例将从SQLite读取数据。首先建立一个程序项目,其含有两个Java程序文件:ac01.java和DataProvider.java。其中,ac01.java是典型的Activity类别,负责UI画面的显示工作,而DataProvider则负责与SQLite沟通。其详细程序代码为:/*ac01.java程序代码*/packagecom.misoo.pklx;importjava.util.ArrayList;importjava.util.HashMap;importjava.util.Map;importandroid.app.ListActivity;importa
7、ndroid.database.Cursor;importandroid.os.Bundle;importandroid.view.View;importandroid.widget.ListView;importandroid.widget.SimpleAdapter;publicclassac01extendsListActivityprivatestaticfinalStringPROJECTION=newString"stud_no","stud_name"OverrideprotectedvoidonCreate(BundlesavedInst
8、anceState)super.onCreate(savedInstanceState);DataProviderdp=newDataProvider(this);Cursorcur=dp.query(PROJECTION,null,null,null);ArrayList<Map<String,Object>>coll=newArrayList<Map<String,Object>>();Map<String,Objectitem;cur.moveToFirst();while(!cur.isAfterLast()item=newHash
9、Map<String,Object>();item.put("c1",cur.getString(O)+","+cur.getString(l);coll.add(item);cur.moveToNext();dp.close();this.setListAdapter(newSimpleAdapter(this,coll,android.R.layout.simple_list_item_1,newString"c1",newintandroid.R.id.textl);OverrideprotectedvoidonLi
10、stItemClick(ListViewl,Viewv,intposition,longid)finish();指令:DataProviderdp=newDataProvider(this);这和一般类别之用法是一样的。ac01对象指名要诞生一个DataProvider的物件。然后呼叫它,如下指令:Cursorcur=dp.query(PROJECTION,null,null,null);这要求SQLite从数据库查询出某些数据。详细的DataProvider.java程序代码如下:/*DataProvider.java程序代码*/packagecom.misoo.pklx;importand
11、roid.content.Context;importandroid.database.Cursor;importandroid.database.SQLException;importandroid.database.sqlite.SQLiteDatabase;importandroid.util.Log;publicclassDataProviderprivatestaticfinalStringDATABASE_NAME="StudDB"privatestaticfinalStringTABLE_NAME="Student"privatefinal
12、intDB_MODE=Context.MODE_PRIVATE;privateSQLiteDatabasedb=null;publicDataProvider(Contextctx)trydb=ctx.openOrCreateDatabase(DATABASE_NAME,DB_MODE,null);catch(Exceptione)Log.e("ERROR",e.toString();return;trydb.execSQL("droptable"+TABLE_NAME);catch(Exceptione)Log.e("ERROR",
13、e.toString();db.execSQL("CREATETABLE"+TABLE_NAME+"("+"stud_no"+"TEXT,"+"stud_name"+"TEXT"+");");Stringsql_1="insertinto"+TABLE_NAME+"(stud_no,stud_name)values('S101','Lily');"Stringsql_2="i
14、nsertinto"+TABLE_NAME+"(stud_no,stud_name)values('S102','Linda');"Stringsql_3="insertinto"+TaBLe_NAME+"(stud_no,stud_name)values('S103','Bruce');"trydb.execSQL(sql_1);db.execSQL(sql_2);db.execSQL(sql_3);catch(SQLExceptione)Log.e(&quo
15、t;ERROR",e.toString();return;publicCursorquery(Stringprojection,Stringselection,StringselectionArgs,StringsortOrder)Cursorcur=db.query(TABLE_NAME,projection,null,null,null,null,null);returncur;publicvoidclose()db.close();这种用法属于非嫡系的用法:在ac01.java程序代码里,其指令:DataProviderdp=newDataProvider(this);明确指定
16、由DataProvider对象来提供服务。反之,嫡系用法则是透过意图(Intent)来请Android代为配对,进而找出适当的ContentProvider对象来为acol对象提供服务。2.2 嫡系SQLite的范例刚才的范例里,我们直接使用DataProvider类别的接口来与SQLite沟通。本节的范例,将替DataProvider配上ContentProvider接口,让ac01对象能透过ContentProvider新接口来沟通。此范例也是从SQLite数据库t取3笔数据;请仔细看看其程序代码的微妙差异:/*ac01.java程序代码*/packagecom.misoo.pkrr;im
17、portjava.util.ArrayList;importjava.util.HashMap;importjava.util.Map;importandroid.app.ListActivity;importandroid.content.Intent;importandroid.database.Cursor;.Uri;importandroid.os.Bundle;importandroid.view.View;importandroid.widget.ListView;importandroid.widget.SimpleAdapter;publicclassac01extendsLi
18、stActivitypublicstaticintg_variable;publicstaticfinalStringAUTHORITY="vider.rx09-02"publicstaticfinalUriCONTENT_URI=Uri.parse("content:/"+AUTHORITY+"/Student");privatestaticfinalStringPROJECTION=newString"stud_no","stud_name"Overrideprot
19、ectedvoidonCreate(BundlesavedInstanceState)super.onCreate(savedInstanceState);Intentintent=getIntent();if(intent.getData()=null)intent.setData(CONTENT_URI);Cursorcur=getContentResolver().query(getIntent().getData(),PROJECTION,null,null,null);ArrayList<Map<String,Object>>coll=newArrayList
20、<Map<String,Object>>();Map<String,Object>item;cur.moveToFirst();while(!cur.isAfterLast()item=newHashMap<String,Object>();item.put("c1",cur.getString(0)+","+cur.getString(1);coll.add(item);cur.moveToNext();this.setListAdapter(newSimpleAdapter(this,coll,andr
21、oid.R.layout.simple_list_item_1,newString"c1",newintandroid.R.id.text1);OverrideprotectedvoidonListItemClick(ListViewl,Viewv,intposition,longid)finish。;指令:Cursorcur=getContentResolver().query(getIntent().getData(),PROJECTION,null,null,null);要求Android代为寻找适合的ContentProvider来提供服务,并不刻意指定由DataP
22、rovider对象来担任。只要合乎ConentProvider接口,且符合意图条件的对象皆可以来为ac01对象提供服务。于是,ac01程序代码就不再直接呼叫DataProvider类别的函数了,而是呼叫ContentProvider接口所提供的函数。再来仔细看看DataProvider类别与ContentProvider接口的搭配情形:/*DataProvider.java程序代码*/packagecom.misoo.pkrr;importandroid.content.ContentProvider;importandroid.content.ContentValues;importandr
23、oid.content.Context;importandroid.database.Cursor;importandroid.database.SQLException;importandroid.database.sqlite.SQLiteDatabase;importandroid.database.sqlite.SQLiteOpenHelper;.Uri;importandroid.util.Log;publicclassDataProviderextendsContentProviderprivatestaticfinalStringDATABASE_NAME="StudN
24、ewDB"privatestaticfinalintDATABASE_VERSION=2;privatestaticfinalStringTABLE_NAME="StudTable"privatestaticclassDatabaseHelperextendsSQLiteOpenHelperDatabaseHelper(Contextcontext)super(context,DATABASE_NAME,null,DATABASE_VERSION);OverridepublicvoidonCreate(SQLiteDatabasedb)db.execSQL(&qu
25、ot;CREATETABLE"+TABLE_NAME+"("+"stud_no"+"TEXT,"+"stud_name"+"TEXT"+");");Stringsql_1="insertinto"+TABLE_NAME+"(stud_no,stud_name)values('S1001','Pam');"Stringsql_2="insertinto"+TABLE_NAME+
26、"(stud_no,stud_name)values('S1002','Steve');"Stringsql_3="insertinto"+TABLE_NAME+"(stud_no,stud_name)values('S1003','John');"trydb.execSQL(sql_1);db.execSQL(sql_2);db.execSQL(sql_3);catch(SQLExceptione)Log.e("ERROR",e.toString()
27、;)OverridepublicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion)/privateDatabaseHelpermOpenHelper;OverridepublicbooleanonCreate()mOpenHelper=newDatabaseHelper(getContext();returntrue;OverridepublicCursorquery(Uriuri,Stringprojection,Stringselection,StringselectionArgs,StringsortOrder)SQLi
28、teDatabasedb=mOpenHelper.getReadableDatabase();Cursorc=db.query(TABLE_NAME,projection,null,null,null,null,null);returnc;OverridepublicStringgetType(Uriuri)returnnull;OverridepublicUriinsert(Uriuri,ContentValuesinitialValues)returnuri;Overridepublicintdelete(Uriuri,Stringwhere,StringwhereArgs)return0
29、;Overridepublicintupdate(Uriuri,ContentValuesvalues,Stringwhere,StringwhereArgs)return0;类别定义:publicclassDataProviderextendsContentProvider/.DataProvider类别继承ContentProvider父类别,也继承了它的接口定义。ContentProvider接口定义了多个函数,主要包括:lquery()函数-它查询出合乎某条件的数据。linsert()函数-它将存入一笔新资料。ldelete()函数-它删除合乎某条件的资料。lupdate()函数-更新某些笔数据的内容。在这个DataProvider类别里,撰写了query()函数内的指令,来实现query()接口,这个query()函数实际呼叫SQLite数据库的功能。也就是说,ac01等应用程序透过ContentProvider接口间接呼叫到DataProvide
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论