标签:android存储 chche sharedpreferences file sd卡存储
SharedPreferences保存的数据只要是类似于配置信息格式的数据,因此它保存的数据主要是简单的key-value对形式。下面关系图
上图完全可以看出,存的时候用SharedPreferences的内部类Editor,取的时候用SharedPreferences。
SharedPreference是接口无法创建实例,Context提供下面方法创建实例 该实例只能有一个,也就是单例模式。
getSharedPreferences(String name,int mode);
public class MainActivity extends Activity { SharedPreferences sp; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //获取SharedPreferences实例 Test是文件名,不要加后缀,默认为XML格式 sp = getSharedPreferences("Test", Context.MODE_WORLD_WRITEABLE); //得到内部类写数据 SharedPreferences.Editor editor = sp.edit(); editor.putString("name", "value"); //不提交则无法获得数据 editor.commit(); } public void btn(View view){ String string = sp.getString("name", "null"); Toast.makeText(this, string, 1).show(); } }存储路径为:data/data/包名/shared_prefs/Test.xml
打开该文件看到
<?xml version="1.0" encoding="utf-8" standalone ="yes" ?> <map> <string name="name">value</string> </map>
存储时长:卸载软件时包名所在的文件夹会消失,所以该文件无法同样会消失。
读写其他应用的SharedPreferences
上述是在本身的APP中玩耍,这次看如何读取其他应用,关键是获得其他应用的程序的Context(代表Android应用的全局信息的接口)又因为包名是Andoird应用的唯一标示,所以调用本APP的Context的方法
createPackageContext("android.example.homework", CONTEXT_IGNORE_SECURITY);
public class MainActivity extends Activity { SharedPreferences sp; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获取SharedPreferences实例 try { //通过包名得到该应用的Context对象 Context context=createPackageContext("com.example.homework", CONTEXT_IGNORE_SECURITY); //用其他应用的Context创建SharedPreferences sp = context.getSharedPreferences("Test", Context.MODE_WORLD_READABLE+Context.MODE_WORLD_WRITEABLE); } catch (NameNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void btn(View view) { String string = sp.getString("name", "null"); Toast.makeText(this, string, 1).show(); } }
上述的读写并不是唯一的,程序员完全可以利用IO流来直接操作本应用和其他应用的SharedPreferences数据,只是Android将他封装好了,很简便。
无法存储自定义类型,主要存储的APP配置信息,例如(用户名,密码等)。
存储空间不够系统会删除Cache存储,但不要依赖系统删除
存:
File dir = getCacheDir(); File file = new File(dir,"test.txt"); try { FileOutputStream fos = new FileOutputStream(file); fos.write("缓冲存储".getBytes()); } catch (Exception e) { // TODO: handle exception }
FileInputStream fis = new FileInputStream(file)
FIle存储就是Android继续使用Java中的IO流继续读写文件的一种方式
两个核心方法:
openFileInput(String name);
openFIleOutput(String name);
下面是简单读写的例子
public class MainActivity extends Activity { SharedPreferences sp; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void readed(View view) { FileInputStream fis = null; StringBuffer sb=null; try { //打开文件输入流 files文件名,这里系统不给添加后缀,不写无后缀 fis = openFileInput("files"); byte[] buff = new byte[1024]; int len = 0; sb = new StringBuffer(); while ((len = fis.read(buff)) != -1) { sb.append(new String(buff, 0, len)); } //关流 fis.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } Toast.makeText(this, sb, 0).show(); } public void writer(View view) { FileOutputStream fos = null; try { // 以追加模式打开文件输出流 fos = openFileOutput("files", MODE_APPEND); // 将流包装成PrintStream PrintStream printStream = new PrintStream(fos); printStream.print("内容啦啦啦啦"); Toast.makeText(this, "写入成功", 0).show(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (fos != null) try { fos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
该文件依然存放在包名下,所以卸载时依然会丢失数据。
使用File存储和SharedPreferences存储的缺点是容量小,因为在应用程序的数据文件夹下。所以才有了SD卡存储。使用SD卡存储总共分为三步:
(1)判断应用是否有读写SD卡权限
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);(2)获得SD卡的目录
File dir = Environment.getExternalStorageDirectory();(3)使用流读写数据
SD卡的权限
<!-- 添加SD卡的创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 添加SD卡写入权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
public class MainActivity extends Activity { private final String FILE_NAME="test.txt"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } /**读取数据*/ public void readed(View view) { BufferedReader bis=null; //当SD状态装备就绪时 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ File dir = Environment.getExternalStorageDirectory(); try { File file = new File(dir, FILE_NAME); FileInputStream fis = new FileInputStream(file); //将fis流包装成BufferedReader bis= new BufferedReader(new InputStreamReader(fis)); String len = null; StringBuffer sb = new StringBuffer(""); while((len=bis.readLine())!=null){ sb.append(len); } Toast.makeText(this, "读到的数据是:"+sb, 0).show(); } catch (Exception e) { e.printStackTrace(); } finally{ if(bis!=null){ try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } } } else Toast.makeText(this, "SD卡不可用", 0).show(); } /**写入数据*/ public void writer(View view) { RandomAccessFile raf = null; if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ File dir = Environment.getExternalStorageDirectory(); File file = new File(dir, FILE_NAME); //用指定文件创建RandomAccessFIle try { raf = new RandomAccessFile(file, "rw"); //将文件记录指针移动到最后 防止再次写入覆盖之前的 raf.seek(file.length()); raf.write("来一个字符串玩玩".getBytes()); Toast.makeText(this, "写入成功", 0).show(); } catch (Exception e) { e.printStackTrace(); } finally{ if(raf!=null){ try { raf.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }
SQLite是轻量级的数据库(底层就是一个数据库文件)一旦应用获得了代表指定数据库的SQLiteDatabase对象,接下来就可以通过该对象来管理,操作数据库了。
(1)获取SQLiteDatabase对象,它代表了与数据库的链接。
(2).调用SQLiteDatabase的方法来执行SQL语句。
(3).操作SQL语句的执行结果,比如用SimpleCursorAdapter封装Cursor
(4).关闭SQLiDatabase,回收资源。
常用方法
//创建(如果不存在)或打开数据库 static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory)
//打卡一个已经存在的数据库 static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags)
public class MainActivity extends Activity { private ListView listview; private SQLiteDatabase db; private EditText editText; private String TABLE_NAME="student"; //创建表语句 private String CREATE_TABLE = "create table "+TABLE_NAME+" (_id integer primary key autoincrement,name varchar(20),age integer)"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化 editText = (EditText) findViewById(R.id.et); listview=(ListView) findViewById(R.id.listivew); //打开或创建数据库(这里需要绝对路径) db=SQLiteDatabase.openOrCreateDatabase("/mnt/sdcard/my.db3", null); if(!exits(TABLE_NAME)){ db.execSQL(CREATE_TABLE); } } @Override protected void onDestroy() { super.onDestroy(); //关闭数据库 if(db!=null&&db.isOpen()) db.close(); } public void btn(View view){ switch (view.getId()) { case R.id.btn1://插入 String str = editText.getText().toString(); String sql = "insert into "+TABLE_NAME+" (name) values ('"+str+"') "; System.out.println(sql); db.execSQL(sql); break; case R.id.btn2://读取 String sql2 = "select * from "+TABLE_NAME+""; Cursor cursor = db.rawQuery(sql2, null); inflateListView(cursor); break; } } public boolean exits(String table){ String sql= "select * from sqlite_master where name="+"'"+table+"'"; System.out.println(sql); Cursor cursor = db.rawQuery(sql, null); if(cursor.getCount()!=0){ return true; } return false; } private void inflateListView(Cursor cursor){ //构建Cursor适配器的同时就是对Cursor封装成为Adapter SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_expandable_list_item_1, cursor, new String[]{"name"}, new int[]{android.R.id.text1},CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); listview.setAdapter(adapter); } }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <EditText android:id="@+id/et" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/btn1" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="btn" android:text="插入 字符串数据" /> <Button android:id="@+id/btn2" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="btn" android:text="取出数据" /> <ListView android:id="@+id/listivew" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> </LinearLayout>
由于是自定义的路径,所以卸载软件依然存在。这种直接使用SQLiteDatabase的方式使用的极少的。
注意:这里主键的列名必须为_id,因为SimpleCursorAdapter只能识别列名为_id的主键。
这种继承SQLiteOpenHelper方式用的还是比较多的。它是Android提供的一个管理数据库的工具类,可用于管理数据库的创建的版本和更新。
常用方法:
synchronized SQLiteDatabase getReadableDatabase();以只读方式打开对应SQLiteDatabase 对象
synchronized SQLiteDatabase getWritableDatabase();以写方式打开对应SQLiteDatabase 对象
abstract void Upgrade(SQLiteDatabase db,int oldVersion,int newVersion);当数据库版本更新时回调该方法。
在获得数据库实例时建议使用getReadableDatabase();如果用getWritableDatabase()一旦磁盘满了,打开数据库就会出错,而getReadableDatabase方法先只读方式打开,就算磁盘空间满了,也不会出错,而是继续使用只读方式。(getReadableDatabase调用时会包含getWritableDatabase)当调用getReadableDatabase()如果数据库不存在调用onCreate(SQLiteDatabase db);存在之后返回该实例
MyDB.java
public class MyDB extends SQLiteOpenHelper { public MyDB(Context context, String name, int version) { super(context, name, null, version); // TODO Auto-generated constructor stub } public SQLiteDatabase db; final String CREATE_TABLE="create table student(_id integer primary key autoincrement,word varchar(20),detail varchar(20))"; //第一次创建数据库的时候调用,当运行第二次时db==null @Override public void onCreate(SQLiteDatabase db) { this.db=db; db.execSQL(CREATE_TABLE); } //软件升级的时候更新表结构调用,当newVersion>oldVersion时,系统自动触发该方法。 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
public class MainActivity extends Activity { String a; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MyDB db = new MyDB(this, "mydb.db3", 1); SQLiteDatabase database = db.getReadableDatabase(); } }
卸载时文件依然丢失。
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:android存储 chche sharedpreferences file sd卡存储
原文地址:http://blog.csdn.net/u010829905/article/details/47028179