1.Android中的SharedPreferences存储数据方式
SharePreferences是用来存储一些简单配置信息的一种机制,使用Map数据结构来存储数据,以键值对的方式存储,采用了XML格式将数据存储到设备中。例如保存登录用户的用户名和密码。只能在同一个包内使用,不能在不同的包之间使用,其实也就是说只能在创建它的应用中使用,其他应用无法使用。
创建的存储文件保存在/data/data/
package com.example.androidsharedpreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
public class MainActivity extends Activity implements OnClickListener {
private EditText keyET;
private EditText valueET;
private Button insertBtn;
private Button deleteBtn;
private Button modifyBtn;
private Button queryBtn;
private Button clearBtn;
private TextView textView;
public static final String DATABASE = "text";
public static final String PATH = "/data/data/com.example.androidsharedpreferences//shared_prefs/text.xml";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
keyET = (EditText) findViewById(R.id.ed_jian);
valueET = (EditText) findViewById(R.id.ed_zhi);
insertBtn = (Button) findViewById(R.id.button1);
deleteBtn = (Button) findViewById(R.id.button2);
modifyBtn = (Button) findViewById(R.id.button3);
queryBtn = (Button) findViewById(R.id.button4);
clearBtn = (Button) findViewById(R.id.button5);
// 用于显示存储文件中数据
textView = (TextView) findViewById(R.id.tv_jiegou);
insertBtn.setOnClickListener(this);
deleteBtn.setOnClickListener(this);
modifyBtn.setOnClickListener(this);
queryBtn.setOnClickListener(this);
clearBtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// 获取SharedPreferences对象
SharedPreferences sp = getSharedPreferences(DATABASE, Activity.MODE_PRIVATE);
// 获取Editor对象
Editor editor = sp.edit();
// 获取界面中的信息
String key = keyET.getText().toString();
String value = valueET.getText().toString();
switch (v.getId()) {
case R.id.button1:
editor.putString(key, value);
editor.commit();
textView.setText(MainActivity.this.print());
break;
case R.id.button2:
editor.remove(key);
editor.commit();
textView.setText(MainActivity.this.print());
break;
case R.id.button3:
editor.putString(key, value);
editor.commit();
textView.setText(MainActivity.this.print());
break;
case R.id.button4:
String result = sp.getString(key, "");
textView.setText("key=" + key + ",value=" + result);
break;
case R.id.button5:
editor.clear();
editor.commit();
textView.setText(MainActivity.this.print());
break;
default:
break;
}
}
/** 获取存储文件的数据 */
private String print() {
StringBuffer buff = new StringBuffer();
BufferedReader reader= null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(PATH)));
String str;
while ((str = reader.readLine()) != null) {
buff.append(str + "/n");
}
} catch (Exception e) {
e.printStackTrace();
}
Log.d("1111111", buff.toString());
return buff.toString();
}
}
demo下载地址:http://download.csdn.net/detail/qq_31546677/9913230
文章参考地址:http://blog.csdn.net/zuolongsnail/article/details/6556703
2.文件存储在介绍文件存储之前我们要先了解内存、外部存储、内部存储三个概念,我们先来考虑一个问题:
打开手机设置,选择应用管理,选择任意一个App,然后你会看到两个按钮,一个是清除缓存,另一个是清除数据,那么当我们点击清除缓存的时候清除的是哪里的数据?当我们点击清除数据的时候又是清除的哪里的数据?读完本文相信你会有答案。
在android开发中我们常常听到这样几个概念,内存,内部存储,外部存储,很多人常常将这三个东西搞混,那么我们今天就先来详细说说这三个东西是怎么回事?
内存,我们在英文中称作memory,内部存储,我们称为InternalStorage,外部存储我们称为ExternalStorage,这在英文中本不会产生歧义,但是当我们翻译为中文之后,前两个都简称为内存,于是,混了。
那么究竟什么是内部存储什么是外部存储呢?
首先我们打开DDMS,有一个File Explorer,如下:
这里有三个文件夹需要我们重视,一个是data,一个是mnt,一个是storage,我们下面就详细说说这三个文件夹。
内部存储
data文件夹就是我们常说的内部存储,当我们打开data文件夹之后(没有root的手机不能打开该文件夹),里边有两个文件夹值得我们关注,如下:
一个文件夹是app文件夹,还有一个文件夹就是data文件夹,app文件夹里存放着我们所有安装的app的apk文件,其实,当我们调试一个app的时候,可以看到控制台输出的内容,有一项是uploading .....就是上传我们的apk到这个文件夹,上传成功之后才开始安装。另一个重要的文件夹就是data文件夹了,这个文件夹里边都是一些包名,打开这些包名之后我们会看到这样的一些文件:
1.data/data/包名/shared_prefs
2.data/data/包名/databases
3.data/data/包名/files
4.data/data/包名/cache
如果打开过data文件,应该都知道这些文件夹是干什么用的,我们在使用sharedPreferenced的时候,将数据持久化存储于本地,其实就是存在这个文件中的xml文件里,我们App里边的数据库文件就存储于databases文件夹中,还有我们的普通数据存储在files中,缓存文件存储在cache文件夹中,存储在这里的文件我们都称之为内部存储。
外部存储外部存储才是我们平时操作最多的,外部存储一般就是我们上面看到的storage文件夹,当然也有可能是mnt文件夹,这个不同厂家有可能不一样。
一般来说,在storage文件夹中有一个sdcard文件夹,这个文件夹中的文件又分为两类,一类是公有目录,还有一类是私有目录,其中的公有目录有九大类,比如DCIM、DOWNLOAD等这种系统为我们创建的文件夹,私有目录就是Android这个文件夹,这个文件夹打开之后里边有一个data文件夹,打开这个data文件夹,里边有许多包名组成的文件夹。
说到这里,我想大家应该已经可以分清楚什么是内部存储什么是外部存储了吧?好,分清楚之后我们就要看看怎么来操作内部存储和外部存储了。
文件的读写常用的是使用:FileOutputStream和FileInputStream下面我们来看demopackage com.example.androidfilestorage;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import android.app.Activity;
import android.content.Context;
public class MainActivity extends Activity implements OnClickListener {
private File json_file, file;
private Button btn_write, btn_read;
private EditText ed_write, ed_read;
private FileOutputStream fos;
FileInputStream inputStream;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
json_file = getFileDir(MainActivity.this, "thumb1");
if (!json_file.exists()) {
json_file.mkdirs();
}
// 建立缓存json数据源文件夹,在没网络的情况下从这里读取数据
file = new File(json_file + "/txt.json");
if (!file.exists()) {
file.getParentFile().mkdirs();
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Log.d("TestFile", "Create the file:" + file.getPath());
btn_write = (Button) findViewById(R.id.btn_inset);
btn_read = (Button) findViewById(R.id.btn_read);
ed_write = (EditText) findViewById(R.id.ed_inset);
ed_read = (EditText) findViewById(R.id.ed_read);
btn_write.setOnClickListener(this);
btn_read.setOnClickListener(this);
}
/**
* 判断内部存储还是外部存储,带SD卡使用外部存储,不带SD卡使用内部存储。
*/
public File getFileDir(Context context, String uniqueName) {
String cachePath;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
|| !Environment.isExternalStorageRemovable()) {
cachePath = context.getExternalFilesDir(uniqueName).getPath();
} else {
cachePath = context.getFilesDir().getPath();
}
return new File(cachePath);
}
@Override
public void onClick(View v) {
String text = ed_write.getText().toString();
switch (v.getId()) {
case R.id.btn_inset:
try {
fos = new FileOutputStream(file);
OutputStreamWriter osw = new OutputStreamWriter(fos);
osw.write(text);
osw.flush();
osw.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
case R.id.btn_read:
try {
inputStream = new FileInputStream(file);
byte[] bytes = new byte[1024];
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
while (inputStream.read(bytes) != -1) {
arrayOutputStream.write(bytes, 0, bytes.length);
}
inputStream.close();
arrayOutputStream.close();
String content = new String(arrayOutputStream.toByteArray());
ed_read.setText(content);
} catch (Exception e) {
}
break;
default:
break;
}
}
}
文件的读写需要的权限:
demo下载地址: http://download.csdn.net/detail/qq_31546677/9913232
文章参考地址:
内部存储和外部存储理解:http://www.cnblogs.com/jingmo0319/p/5586559.html
3.sqlite数据库存储sqlite以前介绍过了在这里就不介绍了需要的参考我的博客:http://blog.csdn.net/qq_31546677/article/details/68486012
4.ContentProvider存储
适用范围
对于什么情况下才会用到自定义的ContentProvider,官方文档的Dev Guide是这样描述的:
如果你想要提供以下的一种或几种特性的时候你才需要构造一个ContentProvider:
你完全不需要ContentProvider来调用一个SQLite数据库,如果这种调用完全在你自己的应用之中。
也就是说,ContentProvider的作用是为别的应用调用本应用中的数据或者文件提供接口,而它也是唯一的跨应用数据传递的接口。如果仅仅是同一个应用中的数据传递,则完全没有必要使用到自定义的ContentProvider。
另一方面,虽然ContentProvider也能组织文件数据或者SharedPreferences(其实也是文件数据)这种数据,但大多数情况下ContentProvider是作为SQLite数据库的调用接口来被继承的。其原因大概是在于重写的query()方法始终需要返回Cursor,而Cursor作为数据库数据的容器,并没有提供直接往Cursor中写入数据的方法。
大体实现步骤
1. 创建一个数据源,例如继承SQLiteOpenHelper创建一个SQLite数据库;
2. 创建一个继承自ContentProvider的类,并重写insert、delete、query、update、getType、onCreate方法,在这些方法中实现对数据源的操作;
3. 在AndroidManifest.xml文件中添加
4. 在本应用或者其它应用的Activity、Service等组件中使用ContentResolver通过对应的URI来操作该自定义ContentProvider。
名词解释
URL
Android各种类型的URI基本上都是有固定格式的,对于ContentProvider而言,一般形如
content://com.test.cp.MyProvider/phone/1
的URI,其中:
content://是固定字段,必需;
com.test.cp.MyProvider表示authority,是AndroidManifest.xml文件中
phone/1表示path,是数据源路径,非必需,其中的phone对于数据库来说可以视为表名,1表示的是该条数据的编号,如果没有则一般认为是返回当前路径(当前表)中的所有数据。
另外还可以根据自己的需要来进一步定义后续的字段。
UriMatch对象
1. 通过new UriMatcher(UriMatcher.NO_MATCH); 实例化,常量NO_MATCH作为参数表示不匹配任何URI;
2. 实例化后调用addURI方法注册URI,该方法有三个参数,分别需要传入URI字符串的authority部分、path部分以及自定义的整数code三者;
3. 在其它地方调用match方法匹配相应的URI,需要传入Uri作为唯一的参数,返回上述自定义的code值。
至于其初始化的位置,如前所述,网上绝大多数示例都将其放入静态域中实例化,原因不明。实际上放到onCreate方法中也没什么问题。
getType方法ContentProvider必须重写的6个方法中,除了初始化方法onCreate以及数据操作的4个方法以外,还有一个getType方法。它的作用是根据URI返回该URI所对应的数据的MIME类型字符串。这种字符串的格式分为两段:“A/B”。其中A段是固定的,集合类型(如多条数据)必须是vnd.android.cursor.dir,非集合类型(如单条数据)必须是vnd.android.cursor.item;B段可以是自定义的任意字符串;A、B两段通过“/”隔开。这个MIME类型字符串的作用是要匹配AndroidManifest.xml文件
demo示例主要代码
package com.example.androidcustomcontentprovider;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
public class MainActivity extends Activity implements OnClickListener {
private Button btnadd, btnqueryall, btndel, btnupdate;
private EditText edtname, edtage;
private ListView lvall;
private int id;
private Uri url;
private String path="content://com.example.androidcustomcontentprovider.myprovider/person";
private List persons;
private SimpleAdapter simpleAdapter;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
List
demo下载地址: http://download.csdn.net/detail/qq_31546677/9913234
文章参考地址:http://www.cnblogs.com/wangfeng520/p/5099465.html
http://blog.csdn.net/zuolongsnail/article/details/6566317
http://blog.csdn.net/worker90/article/details/7016430
http://blog.csdn.net/amazing7/article/details/51324022
5.网络存储
网络操作博主已经讲过了,可以参考博主的这一篇文章基本没问题:http://blog.csdn.net/qq_31546677/article/details/58603185