Android移动开发基础教程(慕课版)(第2版)课件 王坤 第5-9单元 数据存储-综合实战_第1页
Android移动开发基础教程(慕课版)(第2版)课件 王坤 第5-9单元 数据存储-综合实战_第2页
Android移动开发基础教程(慕课版)(第2版)课件 王坤 第5-9单元 数据存储-综合实战_第3页
Android移动开发基础教程(慕课版)(第2版)课件 王坤 第5-9单元 数据存储-综合实战_第4页
Android移动开发基础教程(慕课版)(第2版)课件 王坤 第5-9单元 数据存储-综合实战_第5页
已阅读5页,还剩224页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第5单元数据存储Android移动开发基础教程(慕课版)(第2版)5.1SharedPreferences【知识描述】SharedPreferences用于保存应用程序中少量的数据,例如音乐播放器的播放模式是顺序播放还是随机播放,手机游戏是否打开音效与振动等,这些数据都可以使用SharedPreferences保存。5.1.1SharedPreferences与Editor简介SharedPreferences提供了一个通用的框架,以便开发者可以以键值对的形式将数据持久化。值得注意的是,SharedPreferences只能保存原始的数据类型变量:布尔型变量、浮点型变量、整型变量、长整型变量和字符串变量。MODE_WORLD_WRITEABLE指定创建的文件可以被其他应用程序读写MODE_WORLD_READABLE指定创建的文件可以被其他应用程序读MODE_PRIVATESharedPreferences的默认值,指定创建的文件只能由本应用程序访问5.1.1SharedPreferences与Editor简介SharedPreferences接口本身并没有写数据能力,这种能力是通过Editor对象实现的,可以通过调用SharedPreferences的edit()方法获取Editor对象,Editor对外提供了大量写数据的方法,具体如表5.1所示。方法说明clear()清除SharedPreferences文件中所有的数据commit()Editor完成编辑后,调用该方法提交修改putBoolean(Stringkey,booleanvalue)保存一个布尔型变量putFloat(Stringkey,floatvalue)保存一个浮点型变量putInt(Stringkey,intvalue)保存一个整型变量putLong(Stringkey,longvalue)保存一个长整型变量putString(Stringkey,Stringvalue)保存一个字符串变量remove(Stringkey)从SharedPreferences文件中移除键对应的值表5.1Editor提供的写数据的方法5.1.2SharedPreferences存储的位置和格式任务5.1使用SharedPreferences读写数据本任务在界面上定义了两个按钮,单击其中一个按钮,向SharedPreferences中写入一个随机值;单击另外一个按钮,在界面上显示刚才写入的数值,运行结果如图5.1所示。图5.1使用SharedPreferences读写数据5.1.2SharedPreferences存储的位置和格式【任务代码】MainActivity代码:publicclassMainActivityextendsActivity{privateSharedPreferencesmPreferences;//定义一个SharedPreferences对象

@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();}privatevoidinit(){//调用getSharedPreferences()方法获取SharedPreferences的具体实例mPreferences=getSharedPreferences("demosharepreferences",MODE_PRIVATE);ButtonbtnWrite=(Button)findViewById(R.id.btn_write);//获取“write”按钮

ButtonbtnRead=(Button)findViewById(R.id.btn_read);//获取“read”按钮5.1.2SharedPreferences存储的位置和格式finalTextViewtxtInfo=(TextView)findViewById(R.id.txt_info);btnWrite.setOnClickListener(newView.OnClickListener(){publicvoidonClick(Viewv){SharedPreferences.Editoreditor=mPreferences.edit();//获取Editor对象

intvalue=newRandom().nextInt(1000);//生成一个随机数

editor.putInt("random",value);//将随机数写入SharedPreferences中

mit();//提交Editor所做的修改

}});btnRead.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){intvalue=mPreferences.getInt("random",0);//调用get×××()方法获取指定键对应的数值

txtInfo.setText("Thenumberis:"+value);//显示读取到的数值

} });}}本任务首先调用getSharedPreferences()方法获取了一个SharedPreferences对象,然后调用editor()方法获取Editor对象,将生成的随机数保存到SharedPreferences中。在读取的时候,调用getXXX()方法获取指定键对应的数值。5.1.2SharedPreferences存储的位置和格式调用getSharedPreferences()方法不仅会返回一个SharedPreferences对象,还会创建一个文件用于保存数据,该文件存储在设备的“/data/data/应用包名/shared_prefs”路径下,打开AndroidStudio的DDMS窗口就可以看到,如图5.2所示,demoshareprefeces.xml即创建的SharedPreferences文件。图5.2SharedPreferences文件保存的位置5.2File存储【知识描述】Android中的文件存储支持使用Java原生的File类和一些文件流进行访问,但是Android的存储规则和其他系统的有所不同,它分为内部存储和外部存储。内部存储位于系统中一个特定的位置,写入其中的文件不能在应用之间共享,当应用被卸载后,处于内部存储中的对应文件也被删除。外部存储的路径可以通过Android提供的接口获取。5.2.1读写内部存储文件在开发中,可以将某应用的文件直接保存在设备的内部存储空间中。默认地,保存在内部存储空间中的文件是私有的,其他程序没有权限访问该文件。当该应用被卸载时,这些内部存储的文件也会被移除。内部存储的文件通过I/O流实现读写。Part01FileInputStreamopenFileInput(Stringname)获取内部存储中name文件对应的输入流Part02FileOutputStreamopenFileOutput获取内部存储中name文件对应的输出流,mode指定了打开文件的模式MODE_PRIVATE:该文件只能被当前程序读写。MODE_APPEND:以追加的方式打开文件5.2.1读写内部存储文件任务5.2使用内部存储本任务功能与任务5.1的功能类似,只不过将数据的读写方式由使用SharedPreferences改为使用内部存储。读写内部存储文件的运行结果如图5.4所示。内部存储的文件存储在“/data/data/应用包名/files”路径下,如图5.5所示。图5.4读写内部存储文件的运行结果图5.5内部存储保存文件的位置5.2.1读写内部存储文件【任务代码】MainActivity代码:publicclassMainActivityextendsActivity{privatefinalStringFILE_NAME="hello";//将文件名定义为常量

protectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();}privatevoidinit(){ButtonbtnWrite=(Button)findViewById(R.id.btn_write);ButtonbtnRead=(Button)findViewById(R.id.btn_read);finalTextViewtxtInfo=(TextView)findViewById(R.id.txt_info);btnWrite.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){intvalue=newRandom().nextInt(1000);//生成一个随机值

write(value);//调用write()方法将随机值写入内部存储中5.2.1读写内部存储文件}});btnRead.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){intvalue=read();//调用read()方法从内部存储中读取随机值

txtInfo.setText("Thenumberis:"+value);//显示

}});}privatevoidwrite(intvalue){try{//获取输出流

FileOutputStreamfos=openFileOutput(FILE_NAME,MODE_PRIVATE);fos.write(String.valueOf(value).getBytes());//将数值写入文件中

fos.close();//关闭流5.2.1读写内部存储文件}catch(Exceptione){e.printStackTrace();}}privateintread(){try{FileInputStreamfis=openFileInput(FILE_NAME);//获取输入流

DataInputStreamdis=newDataInputStream(fis);intvalue=dis.readInt();//读取数值

dis.close();//关闭流

fis.close();returnvalue;}catch(Exceptione){e.printStackTrace();return0;}}}5.2.2读写外部存储文件一般情况下,手机的内部存储空间有限,如果需要读写大文件数据,Android提供了相关访问外部存储的方法。读写外部存储文件需要在AndroidManifest.xml文件中配置权限,如下所示:<manifest...><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>...</manifest>5.2.2读写外部存储文件读写外部存储文件的步骤一般如下。调用Environment的getExternalStorageState()方法判断外部存储设备是否可用,如果外部存储设备可读写,则Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)返回true调用Environment的getExternalStorageDirectory()方法获取外部存储器的目录010203使用FileInputStream、FileOutputStream、FileWriter、FileReader等流操作文件读写外部存储上的文件5.3SQLite数据库【知识描述】在应用程序的开发过程中,如果需要存取的数据量比较大,可以考虑使用数据库。Android系统集成了一个轻量级的数据库——SQLite。SQLite不像Oracle、SQLServer、MySQL那样需要单独安装,它只是一个文件,操作比较简单,Android提供了大量的API以支持SQLite读写数据。5.3.1SQLiteDatabase简介SQLiteDatabase代表一个数据库,应用程序获取指定数据库的SQLiteDatabase对象之后,可以调用一系列的方法操作数据库。方法和对应的说明openDatabase(Stringpath,SQLiteDatabase.CursorFactoryfactory,intflags)打开path文件代表的SQLite数据库openOrCreateDatabase(Stringpath,SQLiteDatabase.CursorFactoryfactory)打开path文件代表的SQLite数据库,如果不存在,则创建execSQL(Stringsql)执行SQL(StructureQueryLanguage,结构查询语言)语句execSQL(Stringsql,Object[]bindArgs)执行带占位符的SQL语句insert(Stringtable,StringnullColumnHack,ContentValuesvalues)向表中插入一条数据delete(Stringtable,StringwhereClause,String[]whereArgs)删除表中指定的数据表5.2SQLiteDatabase类中一些常用的方法5.3.1SQLiteDatabase简介update(Stringtable,ContentValuesvalues,StringwhereClause,String[]whereArgs)更新表中指定的数据query(Stringtable,String[]columns,Stringselection,String[]selectionArgs,StringgroupBy,Stringhaving,StringorderBy)按一定条件查询表中的数据query(Stringtable,String[]columns,Stringselection,String[]selectionArgs,StringgroupBy,Stringhaving,StringorderBy,Stringlimit)按一定条件查询表中的数据,并且控制查询的个数。多用于分页rawQuery(Stringsql,String[]selectionArgs)执行带占位符的查询语句beginTransaction()开始一个事务setTransactionSuccessful()设置当前的事务为成功endTransaction()结束一个事务5.3.2创建数据库和表任务5.3创建表,存储学生的考试成绩【任务代码】DBHelper代码:publicclassDBHelperextendsSQLiteOpenHelper{privatestaticfinalintDB_VERSION=1;//数据库版本号

privatestaticfinalStringDB_NAME="student.db";//数据库名称

privatestaticfinalStringTABLE_NAME="score";//创建的表的名称

publicDBHelper(Contextcontext)//接收Context参数的构造方法

{super(context,DB_NAME,null,DB_VERSION);//调用父类构造方法创建数据库

}publicvoidonCreate(SQLiteDatabasedb){//数据库第一次被创建时会回调onCreate()Stringsql="createtableifnotexists"+TABLE_NAME+"(stuNotextprimarykey,stuNametext,stuSextext,stuScoreinteger)";//创建表的语句

db.execSQL(sql);//执行创建表的SQL语句

}@OverridepublicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){}}5.3.2创建数据库和表本任务定义了一个DBHelper类,它继承自SQLiteOpenHelper,调用父类的构造方法super(context,DB_NAME,null,DB_VERSION)会自动创建名为DB_NAME的数据库,数据库第一次被创建时会回调onCreate()方法,可以在其中执行创建表的操作,创建的数据库存储在“/data/data/应用包名/databases”路径下,如图5.6所示。图5.6SQLite数据库保存的位置5.3.3操作SQLite常用类任务5.4访问SQLite数据库,修改学生成绩表本任务在界面上定义4个按钮,它们分别用于触发增加数据、删除数据、修改更新数据、查询数据的操作,运行结果如图5.7所示。图5.7触发访问数据库操作的4个按钮5.3.3操作SQLite常用类【任务代码】MainActivity代码:publicclassMainActivityextendsActivityimplementsOnClickListener{privateDBMgrmDBMgr=null;//用于封装对SQLite数据库的访问操作

protectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();}privatevoidinit(){mDBMgr=newDBMgr(this);//初始化

ButtonbtnAdd=(Button)findViewById(R.id.btn_add);//定义4个按钮

ButtonbtnDelete=(Button)findViewById(R.id.btn_delete);ButtonbtnUpdate=(Button)findViewById(R.id.btn_update);ButtonbtnQuery=(Button)findViewById(R.id.btn_query);btnAdd.setOnClickListener(this);btnDelete.setOnClickListener(this);btnUpdate.setOnClickListener(this);btnQuery.setOnClickListener(this);}5.3.3操作SQLite常用类publicvoidonClick(Viewv){switch(v.getId()){caseR.id.btn_add://增加数据

{Studentstu1=newStudent("201701","aaa","男",95);Studentstu2=newStudent("201702","aaa","女",99);Studentstu3=newStudent("201703","aaa","男",97);List<Student>list=newArrayList<Student>();list.add(stu1);list.add(stu2);list.add(stu3);mDBMgr.add(list);break;}caseR.id.btn_delete: //删除数据

{mDBMgr.delete("201703");break;}5.3.3操作SQLite常用类caseR.id.btn_update://修改数据

{mDBMgr.update("201701",90);break;}caseR.id.btn_query: //查询数据

{List<Student>list=mDBMgr.query();for(Studentstu:list){Log.i("Student",stu.toString());}break;}default:break;}}protectedvoidonDestroy(){mDBMgr.finish();//资源回收工作

super.onDestroy();}}5.3.3操作SQLite常用类DBMgr代码:publicclassDBMgr{privateSQLiteDatabasemDB=null;//定义一个SQLiteDatabase对象

/***构造函数,做一些初始化工作*@paramcontext*/publicDBMgr(Contextcontext){DBHelperhelper=newDBHelper(context);mDB=helper.getWritableDatabase();//获取一个SQLiteDatabase类的实例

}/***关闭数据库操作*/publicvoidfinish(){if(null!=mDB){mDB.close();mDB=null;}5.3.3操作SQLite常用类

}/***向数据库中添加数据*@paramstudents*/publicvoidadd(List<Student>students){if(null==students||students.isEmpty()){return;}for(Studentstu:students){ContentValuesvalues=newContentValues();values.put("stuNo",stu.getStuNo());values.put("stuName",stu.getStuName());values.put("stuSex",stu.getStuSex());values.put("stuScore",stu.getStuScore());mDB.insert("score",null,values);//执行添加操作

}}

/***删除指定学号的学生信息*@paramstuNo学生学号*/publicvoiddelete(StringstuNo){mDB.delete("score","stuNo=?",newString[]{stuNo});}/***更新指定学号的学生考试成绩*@paramstuNo学生学号*@paramscore学生考试成绩*/publicvoidupdate(StringstuNo,intscore){Stringsql="updatescoresetstuScore="+score+"wherestuNo="+stuNo;mDB.execSQL(sql);}/***查询所有学生信息5.3.3操作SQLite常用类*@return返回查询结果*/publicList<Student>query(){List<Student>list=newArrayList<Student>();//执行查询语句

Cursorcursor=mDB.query("score",null,null,null,null,null,null);while(cursor.moveToNext())//遍历查询结果

{Studentstu=newStudent();stu.setStuNo(cursor.getString(cursor.getColumnIndex("stuNo")));stu.setStuName(cursor.getString(cursor.getColumnIndex("stuName")));stu.setStuSex(cursor.getString(cursor.getColumnIndex("stuSex")));stu.setStuScore(cursor.getInt(cursor.getColumnIndex("stuScore")));list.add(stu);}returnlist;}}5.3.3操作SQLite常用类01OPTION查询操作调用表5.2所示的query(Stringtable,String[]columns,Stringselection,String[]selectionArgs,StringgroupBy,Stringhaving,StringorderBy)方法,这里需要查询所有数据,所以除了第一个参数传入表的名称之外,其他参数均传入null。查询结果是一个Cursor对象,Cursor类似于一个集合,可以遍历取出其中的数据。5.3.3操作SQLite常用类添加操作调用表5.2所示的insert(Stringtable,StringnullColumnHack,ContentValuesvalues)方法,数据以键值对的形式保存在ContentValues对象中,然后被插入表中,插入数据后的查询结果如图5.8所示。02OPTION图5.8SQLite插入数据后的查询结果5.3.3操作SQLite常用类修改操作调用表5.2所示的update(Stringtable,ContentValuesvalues,StringwhereClause,String[]whereArgs)方法,更新表中指定的数据,更新数据后的结果如图5.9所示,将学号为202401的学生的考试成绩改为了90分。图5.9SQLite更新数据后的结果03OPTION5.3.3操作SQLite常用类删除操作调用表5.2所示的delete(Stringtable,StringwhereClause,String[]whereArgs)方法,将学号为202403的学生的数据删除,删除数据后的结果如图5.10所示。图5.10SQLite删除数据后的结果04OPTION5.3.4事务在数据库中,事务是指一系列操作的集合,这些操作要么全部成功执行,要么全部不执行。一个典型的例子是银行的转账工作,它包含两个操作:(1)从一个账户扣款;(2)另一个账户增加相应的金额。很明显,这两个操作必须全部成功执行或者全部不执行。SQLite数据库对事务的概念也做了相应的支持,在操作的开始调用beginTransaction()开启一个事务,当一系列的操作完成后,调用setTransactionSuccessful()函数将事务设置为成功,最后调用endTransaction()结束一个事务。5.4项目实战项目5-1持久化RSS源首先定义一个SQLiteHelper类,它继承自SQLiteOpenHelper,用于创建对应的数据库和数据表SQLiteHelper代码:publicclassSQLiteHelperextendsSQLiteOpenHelper{privatestaticfinalintDB_VERSION=1;privatestaticfinalStringDB_NAME="rss.db";//数据库名

privatestaticfinalStringTABLE_NAME="source";//数据表名

publicSQLiteHelper(Contextcontext){super(context,DB_NAME,null,DB_VERSION);}@OverridepublicvoidonCreate(SQLiteDatabasesqLiteDatabase){Stringsql="CREATETABLEIFNOTEXISTS"+TABLE_NAME+"(\n"+"idINTEGERPRIMARYKEYAUTOINCREMENT,\n"+"nametext,\n"+"urltext,\n"+"create_timetext)";sqLiteDatabase.execSQL(sql);}@OverridepublicvoidonUpgrade(SQLiteDatabasesqLiteDatabase,inti,inti1){}}5.4项目实战接着,创建一个PersistMgr类用于访问数据库并对其中的数据做增加、删除和查询操作PersistMgr代码:publicclassPersistMgr{privateSimpleDateFormatdf;privateSQLiteDatabasemDB=null;publicPersistMgr(Contextcontext){SQLiteHelperhelper=newSQLiteHelper(context);mDB=helper.getWritableDatabase();df=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");}publicvoidfinish(){if(null!=mDB){mDB.close();mDB=null;}}5.4项目实战publicvoidaddRSSSource(RSSSourcesource){if(null==source){return;}ContentValuesval=newContentValues();val.put("name",source.getName());val.put("url",source.getUrl());val.put("create_time",df.format(newDate()));mDB.insert("source",null,val);}publicvoiddelete(Stringurl){mDB.delete("source","url=?",newString[]{url});}5.4项目实战publicList<RSSSource>query(){List<RSSSource>result=newArrayList<>();try(Cursorcursor=mDB.query("source",null,null,null,null,null,null,null)){while(cursor.moveToNext()){RSSSourcesource=newRSSSource(cursor.getString(cursor.getColumnIndex("name")),cursor.getString(cursor.getColumnIndex("url")));result.add(source);}}returnresult;}}5.4项目实战最后,改写RSSSourceRepository类,调用PersistMgr类的方法,将对RSS源的操作持久化到SQLite数据库中,在应用退出并重新启动后,仍然可以读取之前保存的RSS源信息RSSSourceRepository代码:publicclassRSSSourceRepository{privateList<RSSSource>sources;privatePersistMgrpersistMgr;privateIRSSSourceChangeCallbackcallback;publicRSSSourceRepository(){this.sources=newArrayList<>();}publicvoidsetContext(Contextcontext){this.persistMgr=newPersistMgr(context);}publicvoidsetCallback(IRSSSourceChangeCallbackcallback){this.callback=callback;}5.4项目实战publicList<RSSSource>getSources(){this.sources=this.persistMgr.query();returnsources;}publicvoidaddSources(StringsourceName,StringsourceUrl){persistMgr.addRSSSource(newRSSSource(sourceName,sourceUrl));}publicvoidremoveSourceByUrl(StringsourceUrl){Iterator<RSSSource>iterator=this.sources.iterator();while(iterator.hasNext()){if(sourceUrl.equalsIgnoreCase(iterator.next().getUrl())){iterator.remove();this.callback.onChanged();break;}}this.persistMgr.delete(sourceUrl);}publicvoidfinish(){this.persistMgr.finish();}}5.4项目实战项目5-2文件浏览器首页首先获取系统外部存储的根目录,然后通过ListView控件列表展示。当单击某个文件夹时,获取单击文件夹的文件路径,通过listFiles()方法获取该路径下的子文件,并根据自定义的比较器对结果进行排序,然后更新ListView的数据,更新显示内容,具体代码如下。图5.11文件列表图5.12下级目录5.4项目实战MainActivity代码:publicclassMainActivityextendsActivity{privateListViewAdaptermAdpter;privateTextViewmTitle;privateFileMgrfileMgr;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//用于显示当前文件的路径

mTitle=(TextView)findViewById(R.id.txt_view);//获取ListView控件

ListViewListView=(ListView)findViewById(R.id.list_view);//自定义AdaptermAdpter=newListViewAdapter(this);init();5.4项目实战ListView.setAdapter(mAdpter);ListView.setOnItemClickListener(newOnItemClickListener(){publicvoidonItemClick(AdapterView<?>parent,Viewview,intpos,longid){//获取当前选择的文件

Filefile=mAdpter.getItem(pos);//更新显示下级目录

change(file);}});}

privatevoidinit(){fileMgr=newFileMgr();//判断外部存储是否可用

if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){Toast.makeText(this,"theexternalstorageisnotavailable",Toast.LENGTH_SHORT).show();return;}5.4项目实战FilerootFile=Environment.getExternalStorageDirectory();mTitle.setText(rootFile.getAbsolutePath());//获取当前目录的子文件列表

List<File>files=fileMgr.getSubFiles(rootFile);mAdpter.updateFiles(files);}privatevoidchange(Filefile){if(!file.isDirectory())//如果不是文件夹,直接返回

{return;}//更新路径的显示

mTitle.setText(file.getAbsolutePath());//获取新的文件列表

List<File>files=fileMgr.getSubFiles(file);//更新文件和视图显示

mAdpter.updateFiles(files);mAdpter.notifyDataSetChanged();}}5.4项目实战在MainActivity中,首先根据Environment.getExternalStorageState()方法判断外部存储是否可用,如果可用,获取外部存储的根目录,然后调用文件管理类FileMgr的方法获取子文件列表,将文件列表设置到ListView自定义的Adapter中。在onCreate()方法中,对ListView的item设置了单击的监听事件,当item被单击后,获取对应的文件对象。如果该文件属于文件夹,则获取子目录,并调用Adapter的notifyDataSetChanged()方法更新文件和视图显示。5.4项目实战ListViewAdapter代码:publicclassListViewAdapterextendsBaseAdapter{privateLayoutInflaterflater;privateList<File>mDatas;publicListViewAdapter(Contextcontext){flater=LayoutInflater.from(context);mDatas=newArrayList<File>();}publicvoidupdateFiles(List<File>files){mDatas.clear();mDatas.addAll(files);}5.4项目实战publicintgetCount(){return(null==mDatas||mDatas.isEmpty())?0:mDatas.size();}@OverridepublicFilegetItem(intpos){if(null!=mDatas&&pos<mDatas.size()){returnmDatas.get(pos);}returnnull;}@OverridepubliclonggetItemId(intposition){return0;}5.4项目实战@OverridepublicViewgetView(intposition,ViewconvertView,ViewGroupparent){if(null==convertView){//为每一个子项加载布局

convertView=flater.inflate(R.layout.view_list_item,null);}//获取子项布局文件中的控件

ImageViewimgView=(ImageView)convertView.findViewById(R.id.view_img);TextViewtxtTitle=(TextView)convertView.findViewById(R.id.view_title);Filefile=getItem(position);//根据position获取数据

if(null!=file){imgView.setImageResource(file.isDirectory()?R.drawable.folder:R.drawable.file);txtTitle.setText(file.getName());}returnconvertView;}5.4项目实战FileMgr代码:publicclassFileMgr{publicList<File>getSubFiles(Filefile){File[]files=file.listFiles(newFilenameFilter(){@Overridepublicbooleanaccept(Filef,Stringname){return!name.startsWith(".");}});System.out.println("files:"+(null==files));if(null!=files){System.out.println("filemgrlength:"+files.length);}List<File>result=Arrays.asList(files);Collections.sort(result,newCustomFileComparator());returnresult;}}5.4项目实战自定义Comparator的代码:publicclassCustomFileComparatorimplementsComparator{@Overridepublicintcompare(Objecto1,Objecto2){Filefile1=(File)o1;Filefile2=(File)o2;if(file1.isDirectory()){if(file2.isFile()){return-1;}returnfile1.getName().compareTo(file2.getName());}if(file2.isDirectory()){return1;}returnfile1.getName().compareTo(file2.getName());}}THANKS第6单元ContentProviderAndroid移动开发基础教程(慕课版)(第2版)6.1ContentProvider和URI简介无论数据的存储方式是什么,ContentProvider以表的形式组织数据,并将其呈现给其他应用程序。例如Android系统内置的用户字典,它会存储用户想要保存的非标准字词的拼写,其数据的组织形式如表6.1所示。每一行表示一条数据记录,每一列表示数据的一个字段。表6.1用户字典的数据示例单词用户ID出现次数语言区域IDMapReduceuser1100en_US1precompileruser14200fr_FR2Appletuser2225fr_CA3constuser1255pt_BR4intuser5100en_UK56.1ContentProvider和URI简介开发者如果想将自己的应用程序中的数据暴露给其他应用,必须继承ContentProvider基类实现数据的增、删、改、查。基类ContentProvider提供了相关的方法供子类实现,具体如表6.2所示。表6.2ContentProvider提供的方法方法abstractbooleanonCreate()其他应用程序第一次访问ContentProvider时会回调该方法,可以在其中做一些初始化操作abstractUriinsert(Uriuri,ContentValuesvalues)子类实现该方法以处理插入请求abstractintdelete(Uriuri,Stringselection,String[]selectionArgs)子类实现该方法以处理删除请求abstractintupdate(Uriuri,ContentValuesvalues,Stringselection,String[]selectionArgs)子类实现该方法以处理更新请求abstractCursorquery(Uriuri,String[]projection,Stringselection,String[]selectionArgs,StringsortOrder)子类实现该方法以处理查询请求abstractStringgetType(Uriuri)获取数据的MIME类型6.1ContentProvider和URI简介Android中URI的形式一般如下:content://authority/XXX。其中content://是固定的格式,类似于网络请求中的http://。authority唯一标识了一个ContentProvider,系统就是根据authority部分找到对应的ContentProvider的。×××部分指向了ContentProvider中的数据,这部分是可以动态改变的。另外,许多内容提供者都允许通过将ID值追加到URI的末尾来准确访问数据表中的某一行记录,例如对于content://user_dictionary/words/4,user_dictionary就是URI的authority部分,words/4表示访问words数据的第4条记录。6.2创建ContentProvider一般在开发过程中,很少需要实现自定义的ContentProvider,因为很少有应用程序需要对外暴露自己的数据。但是,了解ContentProvider的创建过程可以帮助我们更好地理解如何使用ContentResovler访问系统已经提供的ContentProvider。在AndroidManifest.xml中配置该ContentProvider定义一个类,它继承自ContentProvider类,并实现父类的onCreate()、insert()、delete()、update()、query()和getType()方法定义一个名为CONTENT_URI的URI对象,用作该ContentProvider的标识6.2创建ContentProvider任务6.1创建ContentProvider,对外提供学生信息【任务代码】publicclassConstantsimplementsBaseColumns{//URI的authority部分

publicstaticfinalStringAUTHORITY="vider";//ContentProvider的CONTENT_URIpublicstaticfinalUriCONTENT_URI=Uri.parse("content://"+AUTHORITY+"/students");//定义数据的MIME类型(多行数据)

publicstaticfinalStringDATA_TYPE="vnd.android.cursor.dir/.vider.student";//定义数据的MIME类型(单行数据)

publicstaticfinalStringDATA_TYPE_ITEM="vnd.android.cursor.item/vider.student";//数据表的字段

publicstaticfinalString_ID="_id";publicstaticfinalStringSNO="sno";publicstaticfinalStringSNAME="sname";publicstaticfinalStringSAGE="sage";}创建一个工具类用于保存ContentProvider需要用到的常量,示例代码如下6.2创建ContentProviderpublicclassCustomProviderextendsContentProvider{privatestaticfinalUriMatchermatcher=newUriMatcher(UriMatcher.NO_MATCH);privatestaticfinalintSTUDENT_ALL=0;privatestaticfinalintSTUDENT_ITEM=1;privateDBOpenHelpermDBHelper;static{matcher.addURI(Constants.AUTHORITY,"students",STUDENT_ALL);matcher.addURI(Constants.AUTHORITY,"students/#",STUDENT_ITEM);}@OverridepublicbooleanonCreate(){mDBHelper=newDBOpenHelper(getContext(),"students.db",1);returntrue;}@Overridepublicintdelete(Uriuri,Stringselection,String[]selectionArgs){SQLiteDatabasedb=mDBHelper.getWritableDatabase();intnum=0;实现一个类,它继承自ContentProvider类,其中数据的存储方式可以有多种,示例代码采用SQLite进行数据的存取6.2创建ContentProviderswitch(matcher.match(uri))//解析URI{c

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论