Android数据存储培训课程

上传人:仙*** 文档编号:242533241 上传时间:2024-08-27 格式:PPTX 页数:61 大小:404.58KB
返回 下载 相关 举报
Android数据存储培训课程_第1页
第1页 / 共61页
Android数据存储培训课程_第2页
第2页 / 共61页
Android数据存储培训课程_第3页
第3页 / 共61页
点击查看更多>>
资源描述
Click to edit Master title style,Click to edit Master text styles,Second level,Third level,Fourth level,Fifth level,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,Android数据存储,计算机系 康钦马,Android数据存储概述,Android数据存储主要是通过,Shared,Preferences、本地文件和SQLite数据库。,Android是基于Linux系统,每个用户有独立的进程,这些进程之间是不能互相访问的,如果有需要在各个用户之间共享数据,我们需要使用CotentProivder实现。,另外,ContentProvider可以提供一个统一的接口使上层调用者不用关心数据存储的细节问题。,Shared,Preferences,SharedPreferences用于简单的数据存储,是通过“name-value对”的机制存储数据,可以存储一些基本的数据类型包括:Boolean,string,float,long和integer类型。,数据是存储在XML文件中的。,案例,在文本框中输入文字,点击保存按钮,保存文字到SharedPreferences中。为了查看数据是否成功保存并持久化,可以关闭模拟器,重新启动程序后,点击“获取数据”按钮。,保存数据,save.setOnClickListener(new View.OnClickListener() ,Override,public void onClick(View v) ,/,存储数据到,XML,记录文件,SharedPreferences mySharedPreferences = getSharedPreferences(,MYPREFS, MODE_PRIVATE);,/,获得修改所用的,SharedPreferences,对象,SharedPreferences.Editor editor = mySharedPreferences.edit();,editor.putString(TEXT_KEY, text.getText().toString();,/,确定修改,mit();,);,getSharedPreferences方法,MYPREFS参数是我们自己定义的,SharedPreferences文件名,这个文件名是自定义,Android按照这个名字将数据保存成XML文件。,MODE_PRIVATE是数据操作模式,该模式只能是被具有相同的用户ID的应用程序访问,此外还有:,MODE_WORLD_READABLE,可以被其它所有的应用程序读取数据。,MODE_WORLD_WRITEABLE,可以被其它所有的应用程序写入数据。,SharedPreferences.Editor,当我们是SharedPreferences修改数据时候可以使用SharedPreferences.Editor对象。,SharedPreferences.Editor editor = mySharedPreferences.edit();,mit()提交修改后的数据。,获得数据,find.setOnClickListener(new View.OnClickListener() ,Override,public void onClick(View v) ,/,存储数据到,XML,记录文件,SharedPreferences mySharedPreferences = getSharedPreferences(,MYPREFS, MODE_PRIVATE);,String stringPreference;,stringPreference = mySharedPreferences.getString(TEXT_KEY, );,text.setText(stringPreference);,);,SQLite数据库,SQLite是一个开源的嵌入式关系数据库,它在2000年由D. Richard Hipp发布,它的减少应用程序管理数据的开销,SQLite可移植性好,很容易使用,很小,高效而且可靠。SQLite嵌入到使用它的应用程序中,它们共用相同的进程空间,而不是单独的一个进程。从外部看,它并不像一个RDBMS,但在进程内部,它却是完整的,自包含的数据库引擎。,嵌入式数据库的一大好处就是在你的程序内部不需要网络配置,也不需要管理。因为客户端和服务器在同一进程空间运行。SQLite 的数据库权限只依赖于文件系统,没有用户帐户的概念。SQLite 有数据库级锁定,没有网络服务器。它需要的内存,其它开销很小,适合用于嵌入式设备。你需要做的仅仅是把它正确的编译到你的程序。,SQLite数据类型,SQLite是无类型的,这意味着你可以保存任何类型的数据到你所想要保存的任何表的任何列中, 无论这列声明的数据类型是什么,对于SQLite来说对字段不指定类型是完全有效的,如:,Create Table ex1(a, b, c);,SQLite允许忽略数据类型,但是仍然建议在你的Create Table语句中指定数据类型, 因为数据类型对于你和其他的程序员交流, 或者你准备换掉你的数据库引擎。 SQLite支持常见的数据类型, 如:,CREATE TABLE ex2(,a VARCHAR(10),b NVARCHAR(15),c TEXT,d INTEGER,e FLOAT,f BOOLEAN,g CLOB,h BLOB,i TIMESTAMP,j NUMERIC(10,5),k VARYING CHARACTER (24),l NATIONAL VARYING CHARACTER(16);,创建表,CREATE TABLE语句,CREATE TABLE Table_Name,(column_name datatype(size),,column_name datatype(size),,),关系数据类型,字符串数据,数字数据,时间数据,大型对象,字符串数据,固定长度,固定长度的字段总是占据等量的内存空间,不管实际上在它们中间存放的数据量有多少。,可变长度,而可变长度的字符串只占据它们的内容所消耗的内存量,不管它们的最大尺寸是多少。,字符串数据示例,CREATE TABLE Studios,(name CHAR(20),,,city VARCHAR(50),,,state CHAR(2),,,revenue FLOAT),固定长度,可变长度,数字数据,多数数据库都提供至少2,种数字数据类型:一种用于,整数,,另一种用于,浮点数,。另外还有一些数据库提供更加独特的数字类型。,整数,浮点数,数字数据示例,CREATE TABLE Studios,(name CHAR(20),,,city VARCHAR(50),,,state CHAR(2),,,revenue FLOAT),数字,指定键,主键,每个表中只能指定一个主键,PRIMARY KEY,主键示例,还可以在定义列的时候同时指定候选键和主键,以此代替在CREATE TABLE语句结尾处单独的子句中创建键。,CREATE TABLE Studios,(studio_id INTEGER PRIMARY KEY,name CHAR(20) UNIQUE,city VARCHAR(50),state CHAR(2),指定,studio_id,为主键,INSERT语句,语法,INSERT INTO table_dame,(column_list),VALUES,(value_list),table_name是表名称,记录将要添加到该表中。,INSERT语句 示例1,Studios表的INSERT语句,INSERT INTO Studios,VALUES(1,Giant,LosAngeles,CA),INSERT语句 示例2,Studios表中的列分别是:studio_id、name、city和state。因为这些值都按照上述顺序包括在VALUES子句中,所以INSERT语句可以正常工作。,INSERT INTO Studios,(city, state, name, studio_id),VALUES(Burbank, CA, MPM,2),INSERT语句 小结,在多数数据库中,表中的列都按照它们创建的顺序出现。当使用CREATE TABLE创建新的表时,列的顺序将保持为它们在原始语句中指定的顺序。,UPDATE语句,UPDATE语句用来对表中现有的行作改动。UPDATE,语句的结构如下:,UPDATE table,SET column = value,.,WHERE condition,UPDATE语句,UPDATE语句用来对表中现有的行作改动。UPDATE,语句的结构如下:,UPDATE table,SET column = value,.,WHERE condition,UPDATE语句,UPDATE语句有3个部分。第一,必须指定要更新哪一个表。该语句的第二部分是SET子句,应当指定其中要更新的列和要插入的值。最后,WHERE子句可以用来指定表中哪些行将要更新。,UPDATE语句 示例1,更改某工作室的城市和州的UPDATE语句,UPDATE Studios,SET city = New York,state = NY,WHERE studio_id = 1,1 row updated.,UPDATE语句 示例1,可以看到,在SET子句中,将city和state字段都进行了更改。WHERE子句表明只有studioID为1的行才能被更新。在编写只对表中某一行产生影响的UPDATE语句时,在WHERE子句中使用主关键字来确保只有一行受到改变的影响往往是一个好办法。如果忽略UPDATE语句中的WHERE子句,那么在更新表中的所有行都将受到该语句的影响。,UPDATE语句 示例2,用UPDATE来更改表中所有行的语句,UPDATE Studios,SET state = AK,2 rows updated.,SELECT *,FROM Studios,STUDIO_ID NAME CITY STATE,1 Giant New York AK,2 MPM Burbank AK,DELETE语句,DELETE语句也可以用来将记录从表中删除。DEILETE语句的结构非常简单:,DELETE FROM table,WHERE condition,DELETE语句,可选的WHERE子句可用来限制DELETE语句删除的行数。如果忽略WHERE子句,表中所有的行都会被删除。通过使用WHERE子句,可以指定要想删除每行所必须满足的条件。,DELETE语句 示例,删除Studios 表中所有的行,DELETE FROM Studios,WHERE state = AK,2 rows deleted.,Android访问SQLite,在Android访问SQLite,数据库常用有两种方式:,扩展,SQLiteOpenHelper类提供数据访问接口。,扩展ContentProvider类来提供数据访问接口。,SQLiteOpenHelper,SQLiteOpenHelper类对于数据库访问能够实现很好的封装。如果我们在打开之前创建或更新数据库,可以通过实现SQLiteOpenHelper类实现这一需求。,在实现类中覆盖onCreate和onUpgrade方法,以及对应的构造方法。,有关数据库处理的代码片段,DBHelper(Context _context) ,super(_context, DATABASE_NAME, null, DATABASE_VERSION);,context = _context;,Override,public void onCreate(SQLiteDatabase db) ,try ,db.execSQL(CREATE TABLE t_user (,+ _ID INTEGER PRIMARY KEY autoincrement,+ NAME TEXT + ););, catch (Exception e) ,Override,public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) ,db.execSQL(DROP TABLE IF EXISTS t_user);,/ Create a new one.,onCreate(db);,有关UI的代码片段,protected void onCreate(Bundle savedInstanceState) ,super.onCreate(savedInstanceState);,this.setContentView(R.layout.main);,/,初始化,UI,btnAdd = (Button) findViewById(R.id.btnAdd);,btnViewAll = (Button) findViewById(R.id.btnViewAll);,viewAll = (TextView) findViewById(R.id.viewAll);,inputTxt = (EditText) findViewById(R.id.txtInput);,/,初始化,DB,db = new DBHelper(this);,/,初始化监听,OnClickListener listener = new OnClickListener() ,public void onClick(View v) ,if (v.getId() = R.id.btnAdd) ,db.save(inputTxt.getText().toString();, else if (v.getId() = R.id.btnViewAll) ,/,浏览所有数据,Cursor cur = db.loadAll();,StringBuffer sf = new StringBuffer();,cur.moveToFirst();,while (!cur.isAfterLast() ,sf.append(cur.getInt(0).append( : ).append(cur.getString(1).append(n);,cur.moveToNext();,viewAll.setText(sf.toString();,;,btnAdd.setOnClickListener(listener);,btnViewAll.setOnClickListener(listener);,小结,SQLiteDatabase,void execSQL (String sql) ,可以执行插入、删除、修改和建表sql语句。,Cursor query()实现查询。,Cursor,返回的读取数据库查询结果集,主要方法:,moveToFirst是将结果集指针移到第一条记录,isAfterLast 是将判断是否到达最后一条记录之后。,moveToNext是将结果集指针移向后移动一条记录。,遍历游标写法:,. .,c.moveToNext();,while (!c.isAfterLast() ,. .,c.moveToNext();,. .,ContentProvider,由于Android是基于Linux系统,每个用户有比较的进程,这些进程之间是不能互相访问的,如果有需要在各个用户之间共享数据,我们需要使用CotentProivder实现。,在Android中数据存储可以是文件系统,数据库(SQLite等),ContentProvider可以提供一个统一的接口使上层调用者不用关心数据存储的细节问题。,Content URI,A.标准前缀表明这个数据被一个内容提供器所控制。它不会被修改。,B.URI的权限部分;它标识这个内容提供器。对于第三方应用程序,这应该是一个全称类名以确保唯一性。权限在元素的权限属性中进行声明:,C.用来判断请求数据类型的路径。这可以是0或多个段长。这个分段可以没有。,D.被请求的特定记录的ID,如果有的话。这是被请求记录的_ID数值。如果这个请求不局限于单个记录, 这个分段和尾部的斜线会被忽略:,Content URI 总结,content:/media/internal/images 这个URI将返回设备上存储的所有图片,content:/contacts/people/ 这个URI将返回设备上的所有联系人信息,content:/contacts/people/45 这个URI返回单个结果(联系人信息中ID为45的联系人记录),DataProvider的代码片段,Override,public boolean onCreate() ,mOpenHelper = new DatabaseHelper(getContext();,return true;,public Uri insert(Uri uri, ContentValues values) ,SQLiteDatabase db = mOpenHelper.getWritableDatabase();,long rowId = db.insert(TABLE_NAME, null, values);,Log.v(TAG, insert Table t_user ok);,if (rowId 0) ,Uri insertedUri = ContentUris.withAppendedId(uri, rowId);,getContext().getContentResolver(),.notifyChange(insertedUri, null);,return insertedUri;,throw new SQLException(Failed to insert row into + uri);,解释,Uri insertedUri = ContentUris.withAppendedId(uri, rowId);,重新构建一个URI对象,如果uri是content:/contacts/people, rowId是45。重新构建的URI是content:/contacts/people/45,getContext().getContentResolver().notifyChange(insertedUri, null);,notifyChange()方法则用来通知注册在此URI上的观察者(observer)数据发生了改变。最后返回删除或修改数据的行数。,DataProvider的代码片段,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 int update(Uri uri, ContentValues values, String where,String whereArgs) ,String rowId = uri.getPathSegments().get(1);,SQLiteDatabase db = mOpenHelper.getReadableDatabase();,int count = db.update(TABLE_NAME, values, _ID = + rowId,+ (!TextUtils.isEmpty(where) ? AND ( + where + ) : ), whereArgs);,return count;,DataProvider的代码片段,Override,public int delete(Uri uri, String where, String whereArgs) ,String rowId = uri.getPathSegments().get(1);,SQLiteDatabase db = mOpenHelper.getReadableDatabase();,int count = db.delete(TABLE_NAME, _ID = + rowId,+ (!TextUtils.isEmpty(where) ? AND ( + where + ) : ),whereArgs);,return count;,Override,public String getType(Uri uri) ,return null;,DatabaseHelper,的代码片段,private class DatabaseHelper extends SQLiteOpenHelper ,DatabaseHelper(Context _context) ,super(_context, DATABASE_NAME, null, DATABASE_VERSION);,Override,public void onCreate(SQLiteDatabase db) ,try ,db.execSQL(CREATE TABLE t_user (,+ _ID INTEGER PRIMARY KEY autoincrement,+ NAME TEXT + ););,Log.v(TAG, Create Table t_user ok);, catch (Exception e) ,Log.v(TAG, Create Table t_user err,table exists.);,Override,public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) ,db.execSQL(DROP TABLE IF EXISTS t_user);,onCreate(db);,调用的Activity代码片段,if (v.getId() = R.id.btnAdd) ,/,增加,ContentValues values = new ContentValues();,values.put(NAME, inputId.getText().toString();,getContentResolver().insert(CONTENT_URI, values);,/ db.close();, else if (v.getId() = R.id.btnViewAll) ,/,浏览所有数据,Cursor cur = getContentResolver().query(CONTENT_URI,new String _ID, NAME , null, null, null);,StringBuffer sf = new StringBuffer();,cur.moveToFirst();,while (!cur.isAfterLast() ,sf.append(cur.getInt(0).append( : ).append(,cur.getString(1).append(n);,cur.moveToNext();,/ db.close();,viewAll.setText(sf.toString();, else if (v.getId() = R.id.btnDelete) ,/,删除数据,long selectedID = new Long(inputId.getText().toString();,Uri deletedUri = ContentUris.withAppendedId(CONTENT_URI,selectedID);,getContentResolver().delete(deletedUri, null, null);,使用CursorAdapter,在UI部分会使用Adapter绑定ListView,CursorAdapter是将数据库查询得到的Cursor对象绑定到ListView的对象。,由于CursorAdapter是一个抽象类,所以我们可以使用自己定义的CursorAdapter,也可以使用Android SDK提供的SimpleCursorAdapter。,SimpleCursorAdapter,构造方法,SimpleCursorAdapter(Context context, int layout, Cursor c, String from, int to),context,是上下文对象,layout,布局文件的id,c,数据库或的游标对象,from,数据表查询字段,to,布局文件中控件的id,它们要与from一一对应。,final Cursor c = /,调用查询方法获得游标对象,String from = new String People.NAME;,int to = new int R.id.itemTextView ;,SimpleCursorAdapter adapter,= new SimpleCursorAdapter(getApplicationContext(),R.layout.listitemlayout,c, from, to);,小结,SimpleCursorAdapter,使用的数据库表必须具有一个名字为”_id”的 INTEGER的主键字段。,_id INTEGER PRIMARY KEY autoincrement,SQLite中文乱码问题。,byte bname = c.getBlob(1);,String name = ;,try ,name = new String(bname, GBK);, catch (UnsupportedEncodingException e) ,e.printStackTrace();,CursorAdapter中文问题,由于SQLite中文问题也会导致SimpleCursorAdapter产生中文问题。,通过自定义CursorAdapter解决中文问题。,自定义CursorAdapter中文问题,自定义CursorAdapter需要继承CursorAdapter抽象类,需要重新newView 和bindView方法。,newView方法,创建一个View。,bindView方法,把Cursor中的数据绑定到ListView中,我们要在这个方法中实现中文转换。,构造方法,public GBKCursorAdapter(Context context, int layout_listitem,Cursor c, String cols, Class clz, int itemviews) ,super(context, c);,this.mInflater = LayoutInflater.from(context);,this.layout_listitem = layout_listitem;,this.clz = clz; /,字段的类型,this.cols = cols; /,字段的列名,this.itemviews = itemviews; /,绑定的控件名,newView方法实现,Override,public View newView(Context context,Cursor cursor, ViewGroup parent) ,final View view = mInflater,.inflate(layout_listitem, parent, false);,return view;,bindView方法实现,Override,public void bindView(View view, Context context, Cursor cursor) ,for (int i = 0; i cols.length; i+) ,TextView text = (TextView) view.findViewById(itemviewsi);,if (clzi = Integer.class) ,text.setText(String.valueOf(cursor.getInt(cursor,.getColumnIndex(colsi);,. .,if (clzi = String.class) ,byte b = cursor.getBlob(cursor.getColumnIndex(colsi);,try ,text.setText(new String(b, GBK);, catch (UnsupportedEncodingException e) ,text.setText(cursor.getString(cursor,.getColumnIndex(colsi);,在Activity中调用,. .,GBKCursorAdapter sca = new GBKCursorAdapter(,getApplicationContext(), R.layout.my_listitem, c,new String _id, NAME ,new Class Integer.class, String.class ,new int R.id.ItemTitle, R.id.ItemText );,. .,listView.setAdapter(sca);,. .,问题解决,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!