您的位置:首页 > 移动开发 > Android开发

Android中数据存储和访问方式

2015-10-18 17:30 567 查看
Android中数据存储和访问方式一般有5种:

1,文件

2,SharedPreferences

3,SQLite数据库

4,ContentProvider

5,网络

一、文件

1-1,写入文件到手机

private void writeFile(String filename){
try {
FileOutputStream  fos = this.openFileOutput(filename, Context.MODE_PRIVATE);
fos.write("试验测试文件".getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
1-2,从手机中读取文件

private void readFile(String filename) {
try {
FileInputStream fis = this.openFileInput(filename);
String content = readInStream(fis);
Log.i("readFile", content);
} catch (Exception e) {
e.printStackTrace();
}
}

public static String readInStream(FileInputStream inStream) {
try {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = -1;
while ((length = inStream.read(buffer)) != -1) {
// 0-起始位置,length-个数
// 将buffer数组从下标0开始的length个字节数据写入到内存输出流中
//下次循环存入时outStream中的字节数组下标增长一个length
outStream.write(buffer, 0, length);
}
outStream.close();
inStream.close();
return outStream.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
2-1,写入文件到SDCard

注意:写文件到SDCard需要权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
private void saveFileToSD(String content, String filename) {
// 首先判断手机是否安装了SD卡
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
File SdDir = Environment.getExternalStorageDirectory();

File file = new File(SdDir, filename);
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
fos.write(content.getBytes());
fos.close();
} catch (Exception e) {
Log.i("SaveToSD", "fail");

}
} else {
Toast.makeText(this, "未安装SD卡", Toast.LENGTH_LONG).show();
}
}


二、SharedPreferences 用于对软件配置参数的保存,背后是使用的XML格式保存

1,写入到SharedPreferences数据

private void saveToSP(String name, String password) {
// 拿到一个SharedPreferences
SharedPreferences sp = this.getSharedPreferences("config", Context.MODE_PRIVATE);
//获取编辑器
Editor editor = sp.edit();
editor.putString("name", name);
editor.putString("password", password);
//提交修改
editor.commit();
}
2-1,从本应用的SharedPreferences中读取数据

private Map<String,String> readFromSP() {
//
SharedPreferences sp = this.getSharedPreferences("config",Context.MODE_PRIVATE);
Map<String, String> map = (Map<String, String>) sp.getAll();
return map;
}
2-2,从其他应用的SharedPreferences中读取数据

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 写入文件
// writeFile("filename.txt");
// 读取文件
// readFile("filename.txt");
// 把文件写入SD卡
// saveFileToSD("save file to sdcard...", "file.txt");
// 使用preferences保存
// saveToSP("libing","123456");
// 从SharedPreferences中读取数据
Context otherAppContext;
try {
//获取其他应用的Context
otherAppContext = createPackageContext("com.example.sms",
Context.CONTEXT_IGNORE_SECURITY);
Map<String, String> data = readFromOtherSP(otherAppContext);
Log.i("Map", data.toString());
} catch (NameNotFoundException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}

}

@SuppressLint("WorldReadableFiles")
private Map<String, String> readFromOtherSP(Context context) {
@SuppressWarnings("deprecation")
SharedPreferences sp = context.getSharedPreferences("config",
Context.MODE_WORLD_READABLE);
@SuppressWarnings("unchecked")
Map<String, String> map = (Map<String, String>) sp.getAll();
return map;
}


三、SQLite数据库

使用SQLite数据库操作有两种方式:一种是利用execSQL()和rawQuery()执行SQL语句对数据进行操作;此外,SQLiteDatabase还专门提供了对应于添加、删除、更新、查询的操作方法: insert()、delete()、update()和query() 。

1,利用execSQL()和rawQuery()执行SQL语句

private String query(SQLiteDatabase db, String name) {
// TODO 自动生成的方法存根
Cursor cursor = db.rawQuery("select * from person where name=?",
new String[] { name });
Map<Integer,String> map = new HashMap<Integer,String>();
String data;
int id,age,i=0;
String username;
while (cursor.moveToNext()) {
id = cursor.getInt(0);
username = cursor.getString(1);
age = cursor.getInt(2);
data = Integer.toString(id) +" "+ username+" "
+ Integer.toString(age);
map.put(++i, data);
}
cursor.close();
return map.toString();
}

private void update(SQLiteDatabase db, String newValue, String oldValue) {
// TODO 自动生成的方法存根
// db.execSQL("update person set name='"+newValue+"'"+
// " where name='"+oldValue+"'");
// 改进版
db.execSQL("update person set name=? where name=?", new Object[] {
newValue, oldValue });
}

private void delete(SQLiteDatabase db, String name) {
// SQL语句直接拼装
db.execSQL("delete from person where name='" + name + "'");
// 使用改进的方式
db.execSQL("delete from person where name=?", new Object[] { name });
}

private void add(SQLiteDatabase db, String name, int age) {
// 无特殊字符时可以直接用SQL语句来拼装
// db.execSQL("insert into person(name,age) values("+"'"+name+"'"+","+Integer.toString(age)+")");
// 有特殊字符时
db.execSQL("insert into person(name,age) values(?,?)", new Object[] {
name, age });

}

2,SQLiteDatabase还专门提供了对应于添加、删除、更新、查询的操作方法: insert()、delete()、update()和query()

private String query(SQLiteDatabase db, String table, String name) {
Cursor cursor = db.query(table, new String[] { "personid", "name",
"age" }, "name=?", new String[] { name }, null, null,
"personid desc");
Map<Integer, String> map = new HashMap<Integer, String>();
String data;
int id, age, i = 0;
String username;
while (cursor.moveToNext()) {
id = cursor.getInt(0);
username = cursor.getString(1);
age = cursor.getInt(2);
data = Integer.toString(id) + " " + username + " "
+ Integer.toString(age);
map.put(++i, data);
}
cursor.close();
return map.toString();
}

private void update(SQLiteDatabase db, String table, String newValue,
String oldValue) {
ContentValues values = new ContentValues();
values.put("name", newValue);
db.update(table, values, "name=?", new String[] { oldValue });
}

private void delete(SQLiteDatabase db, String table, String name) {
db.delete(table, "name=?", new String[] { name });
}

private void add(SQLiteDatabase db, String table, String name, int age) {
ContentValues values = new ContentValues();
values.put("name", name);
values.put("age", age);
db.insert(table, null, values);
}


3,使用事务操作SQLite数据库

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

MyOpenHelper openHelper = new MyOpenHelper(this);
SQLiteDatabase db = openHelper.getWritableDatabase();
db.beginTransaction();//开启一个事务
try{
// 增
add(db, "person", "libing", 23);
// 删
delete(db,"person","libing");
// 改
update(db,"person","libingbing","libing");
db.setTransactionSuccessful();//如果执行此语句,则说明修改完成
// 查
String data = query(db,"person", "libing");
Log.i("content of database", data);
}
finally{
db.endTransaction();//如果db.setTranscationSuccessful()执行,则此处提交;否则回滚。
db.close();
}
}


四、ContentProvider内容提供者,对外共享数据

ContentProvider中操作的数据可以来自数据库,也可以是文件、xml或网络等其他存储方式

1,以操作数据库为例

1)首先编写类继承ContentProvider

public class PersonContentProvider extends ContentProvider {
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private static final int PERSONS = 1;
private static final int PERSON = 2;
private DBOpenHelper dbOpenHelper;
static {
matcher.addURI("com.example.contentprovider.personprovider", "person", PERSONS);
matcher.addURI("com.example.contentprovider.personprovider", "person/#", PERSON);
}
//被创建时回调
@Override
public boolean onCreate() {
dbOpenHelper = new DBOpenHelper(this.getContext());
return true;
}
//增
//参数(Uri uri, ContentValues values)向uri中添加values内容
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
long id = 0;
switch (matcher.match(uri)) {
case PERSONS:
id = db.insert("person", "personid", values);//  insert into person (personid) values(null)
getContext().getContentResolver().notifyChange(uri, null);
return ContentUris.withAppendedId(uri, id);// 返回代表新增记录的Uri
case PERSON:
id = db.insert("person", "personid", values);
String strUri = uri.toString();
Uri personUri = Uri.parse(strUri.substring(0,
strUri.lastIndexOf("/")));
getContext().getContentResolver().notifyChange(personUri, null);
return ContentUris.withAppendedId(personUri, id);
default:
throw new IllegalArgumentException("Unkown Uri:" + uri);
}
}
//删
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
int num = 0;// 已经删除的记录数量
switch (matcher.match(uri)) {
case PERSONS:
num = db.delete("person", selection, selectionArgs);
break;
case PERSON:
long id = ContentUris.parseId(uri);
String where = "personid=" + id;
if (selection != null && !"".equals(selection)) {
where = where + " and " + selection;
}
num = db.delete("person", where, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unkown Uri:" + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return num;
}

//改
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
int num = 0;// 已经修改的记录数量
switch (matcher.match(uri)) {
case PERSONS:
num = db.update("person", values, selection, selectionArgs);
break;
case PERSON:
long id = ContentUris.parseId(uri);
String where = "personid=" + id;
if (selection != null && !"".equals(selection)) {
where = where + " and " + selection;
}
num = db.update("person", values, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unkown Uri:" + uri);
}
getContext().getContentResolver().notifyChange(uri, null);// 通知数据发生变化
return num;
}

//查
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
switch (matcher.match(uri)) {
case PERSONS:
return db.query("person", projection, selection, selectionArgs,
null, null, sortOrder);

case PERSON:
long id = ContentUris.parseId(uri);
String where = "personid=" + id;
if (selection != null && !"".equals(selection)) {
where = where + " and " + selection;
}
return db.query("person", projection, where, selectionArgs, null,
null, sortOrder);

default:
throw new IllegalArgumentException("Unkown Uri:" + uri);
}
}
@Override
public String getType(Uri uri) {// 返回当前操作的数据类型
switch (matcher.match(uri)) {
case PERSONS:// 操作的是集合类型数据
return "vnd.android.cursor.dir/person";
case PERSON:
return "vnd.android.cursor.item/person";
default:
throw new IllegalArgumentException("Unkown Uri:" + uri);
}
}

}


2)然后用ContentResolver对ContentProvider数据操作

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

ContentResolver resolver = this.getContentResolver();
// 增加记录
ContentValues values = new ContentValues();
values.put("name", "libing");
values.put("age", 23);

Uri uri = resolver
.insert(Uri
.parse("content://com.example.contentprovider.personprovider/person"),
values);
values.clear();
values.put("name", "libing");
values.put("age", 34);
Uri uri1 = resolver
.insert(Uri
.parse("content://com.example.contentprovider.personprovider/person"),
values);
values.clear();
Log.i("Uri-add", Long.toString(ContentUris.parseId(uri1)));
// 删除记录
//		resolver.delete(
//				Uri.parse("content://com.example.contentprovider.personprovider/person"),
//				"name=? and age=?", new String[] { "libing", "23" });
// 修改记录
values.put("name", "minmin");
values.put("age", 23);
resolver.update(
Uri.parse("content://com.example.contentprovider.personprovider/person"),
values, "age=34", null);
//查询记录
Cursor cursor = resolver.query(Uri.parse("content://com.example.contentprovider.personprovider/person"),
null, "name=? or name=?", new String[]{"minmin","libing"}, "personid");
while(cursor.moveToNext()){
Log.i("CURSOR", cursor.getInt(0)+" "+cursor.getString(1)+" "+cursor.getInt(2));

}
cursor.close();
}


五、从网络获取数据

1,使用Socket进行通信

1)服务器端的程序,一般以PC机作为服务器端,因为手机的IP地址是由运营商动态分配,而PC的IP一般固定。

public static void main(String[] args) throws IOException {
// TODO 自动生成的方法存根

ServerSocket ss = new ServerSocket(30000);
while(true){
Socket socket = ss.accept();
OutputStream os = socket.getOutputStream();
os.write("服务器已经接受您的请求。。。".getBytes("utf-8"));
os.close();
socket.close();

}

}


2)客户端的程序:

网络连接属于耗费时间的操作,故应该开启新的线程来完成,避免阻塞主线程。

new Thread(){
public void run(){
try{
Socket socket = new Socket("172.24.36.95", 30000);
//获得输入流,输入流是字节流信息,故需要转化成字符流
//而InputStreamReader正是字节流到字符流的桥梁,它能将字节流解码为字符流
//为了提高转换效率,用BufferdReader对其进行包装
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while((line=br.readLine())!=null){
sb.append(line);
}
Log.i("information from server", sb.toString());
br.close();
socket.close();

}catch(Exception e){
e.printStackTrace();
}
}
}.start();


2,使用URL访问网络资源

1)使用URL

ImageView imageView;
Bitmap bitmap;

Handler myHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0x110) {
imageView.setImageBitmap(bitmap);
}
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//		socketLink("172.24.36.95", 30000);

imageView = (ImageView) this.findViewById(R.id.iv_1);
try {
urlLink(new URL(
"http://p3.wmpic.me/article/2015/02/10/1423552790_HGrFkNfN.jpg"));
} catch (MalformedURLException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}

}


2)使用URLConnection

待整理。。

3,使用HTTP访问网络

待整理。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: