学习内容:
Android的数据存储....
1.使用SharedPreferences来保存和读取数据...
2.使用File中的I/O来完成对数据的存储和读取...
一个应用程序,经常需要与用户之间形成交互...需要保存用户的设置和用户的数据信息...这些都离不开数据的存储...Android的数据采用五种方式来进行存储...在这里就先介绍两种存储方式...
1.使用SharedPreferences存储数据...
对于软件配置参数的保存,Windows系统采用ini文件来进行保存,java程序中则会使用properties属性文件或者是xml文件来完成数据的存储...而Android平台为我们提供了一个SharedPreferences接口来保存数据信息的,SharedPreferences与我们在JAVA中学习的HashTableZ有点相似,SharedPreferences也是通过保存键值对的形式来完成对数据的保存...但是它仅仅能保存的是基本数据类型的数据,无法像HashTable那样可以保存对象...
具体的实现方式有几个步骤:
i.首先我们需要获取SharedPreferences对象...需要调用getSharedPreferences(String name,int mode)方法来进行获取...String表示的指定文件名称...mode表示数据的操作模式...这个操作模式的含义就是我们保存的数据是允许和其他应用程序形成共享呢?还是仅仅是在自己的应用程序中才能对这个数据进行操作...这个参数系统给了几种特定的模式...
常量 | 描述 |
public static final int MODE_PRIVATE | 表示创建的文件数据是私有数据,只能在本身的应用程序中进行调用,在这种模式下写入的内容会覆盖掉原来的内容 |
public static final int MODE_WORLD_READABLE | 允许替他文件读取该文件数据 |
public static final int MODE_WORLD_WRITEABLE | 允许其他文件写入数据到该文件 |
SharedPreferences sp=super.getSharedPreferences("MusicService", MODE_WORLD_READABLE);
ii.由于SharedPreferences本身是不支持对数据进行存储和修改的,只允许获取数据,那么存储和修改数据就需要使用到SharedPreferences.Editor接口...因此第二步就是通过edit方法来获取Editor对象...
SharedPreferences.Editor edit=sp.edit();
iii.接着就是通过put("key","value")方法来进行数据的存储...然后使用commit()方法来提交数据,提交数据的目的就是完成数据的更新...
edit.putString("collage","hinst");
edit.putInt("students",20000);
列举一个例子,记录音乐的播放进度,在下次播放的时候在记录的位置进行播放...通过调用服务的方式来完成....
package com.example.musicsharedpreferences; import android.app.Service; import android.content.Intent; import android.content.SharedPreferences; import android.media.MediaPlayer; import android.os.IBinder; import android.widget.Toast; public class Serice extends Service{ private MediaPlayer mp=new MediaPlayer(); @Override public void onCreate(){ Toast.makeText(getApplicationContext(), "Service is create", Toast.LENGTH_SHORT).show(); mp.create(getApplicationContext(), R.raw.java);//设置播放的音乐的资源位置... mp.setLooping(true);//是否循环... } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub Toast.makeText(getApplicationContext(), "Service is bind", Toast.LENGTH_SHORT).show(); SharedPreferences sp=super.getSharedPreferences("MusicService", MODE_WORLD_READABLE); mp.seekTo(sp.getInt("Content", 0)); //设置播放的位置为保存的进度... mp.start(); return null; } @Override public boolean onUnbind(Intent intent){ Toast.makeText(getApplicationContext(), "Service is onBind", Toast.LENGTH_SHORT).show(); SharedPreferences sp=super.getSharedPreferences("MusicService", MODE_WORLD_READABLE); Toast.makeText(getApplicationContext(), "Context"+mp.getCurrentPosition(), Toast.LENGTH_SHORT).show(); SharedPreferences.Editor edit=sp.edit();//获取Eidtor对象来获取存储修改数据的权限... edit.putInt("Content", mp.getCurrentPosition());//将进度值进行保存,以键值对的方式... edit.commit();//提交数据,完成更新操作... mp.stop(); return false; } }
在主函数中通过绑定服务来完成...
package com.example.musicsharedpreferences; import android.os.Bundle; import android.os.IBinder; import android.app.Activity; import android.content.ComponentName; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.view.Menu; import android.view.View; import android.widget.Toast; public class MainActivity extends Activity implements View.OnClickListener { final ServiceConnection con=new ServiceConnection() {//通过实现这个接口,完成Service的调用... @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub } @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.bind).setOnClickListener(this); findViewById(R.id.unbind).setOnClickListener(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public void onClick(View v) { // TODO Auto-generated method stub ContentValues cv=new ContentValues(); switch(v.getId()){ case R.id.bind: Intent intent=new Intent(MainActivity.this,com.example.musicsharedpreferences.Serice.class); Toast.makeText(getApplicationContext(), "bindService", Toast.LENGTH_SHORT).show(); bindService(intent, con, Context.BIND_AUTO_CREATE); break; case R.id.unbind: Toast.makeText(getApplicationContext(), "unbindService", Toast.LENGTH_SHORT).show(); unbindService(con); break; } } }
这样就完成了音乐播放进度的保存...将数据以键值对的形式进行临时的保存,然后在通过获取数据完成一些相应的操作...但是SharedPreferences只能保存基本的数据类型..如果想保存更多类型的数据就要使用文件进行保存数据信息...
2.使用File来完成对数据的存储...
File就可以存储其他类型的数据,File实际上就是通过I/O流的形式对数据进行存储,Android中的文件数据一般保存在手机内存中或者是保存在外部的SD卡中...在这里就不引入什么控件了...就单纯的介绍一下Android中如何使用这种方式来完成数据的存储...有过java基础的基本都知道是怎么回事...
package com.example.filesave; /*使用File来读取手机内存中的数据 * * * */ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream; import java.util.Scanner; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { private FileOutputStream output; private FileInputStream input; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); try { output=super.openFileOutput("data.txt", Activity.MODE_PRIVATE); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } PrintStream print=new PrintStream(output);//将输出流进行封装... print.println("a"); print.println("b"); print.println("c"); print.close(); try { input=super.openFileInput("data.txt"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } Scanner scan=new Scanner(input); while(scan.hasNext()){ System.out.println(scan.next()+" "); } scan.close(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
这里简单的说一下为什么要将output进行封装,估计大家也知道这么去用,但是却不知道为什么要这么去用,这里将output进行封装的目的是通过封装这个对象,我们就可以在这个新的类中去调用原来这个类里的内部方法,我们可以把被封装对象的方法进行重写,然后按照我们重写的这种方法来实现某种功能...就是我们可以在这个装饰类内去调用被装饰类的方法..这里通过将output进行封装,然后通过重写方法,最后使用println()的形式来完成了数据的输出...相比output里的输出方法就方便了很多...这个装饰者模式说白了就是装饰类可以调用被装饰类里的方法,不仅可以调用,甚至是可以重写...这样就完成了方法的调包....
使用File读取内存卡中的数据...
内存卡的使用目的是为了节省手机内存的空间,将大型的数据信息保存在内存卡中,以保证手机的运行速度更快...那么如何读取内存卡中的数据呢?这个也是非常的简单的...唯一的需要就是要对内存卡是否存在进行具体判断...然后设置相应的读写权限就可以完成在内存卡上进行存取数据的操作...
package com.example.filesave; /*使用File来读取手机内存中的数据和内存卡中的数据信息... * * * */ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream; import java.util.Scanner; import android.os.Bundle; import android.os.Environment; import android.app.Activity; import android.view.Menu; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv=(TextView) findViewById(R.id.show); if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ File file =new File(Environment.getExternalStorageDirectory().toString()+File.separator+"hinst"+File.separator+"hinst.txt"); if(!file.getParentFile().exists()){ file.getParentFile().mkdirs(); } PrintStream print=null; try { print=new PrintStream(new FileOutputStream(file,true)); print.println("山东理工,计算机学院,计科1304"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(print!=null){ print.close(); }else{ Toast.makeText(getApplicationContext(), "内存卡不存在", Toast.LENGTH_SHORT).show(); } } } if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ File file=new File(Environment.getExternalStorageDirectory().toString()+File.separator+"hnist"+File.separator+"hnist.txt"); if(!file.getParentFile().exists()){ file.getParentFile().mkdirs(); } Scanner scan=null; try { scan=new Scanner(new FileInputStream(file)); while(scan.hasNext()){ tv.setText(scan.hasNext()+" "); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(scan!=null){ scan.close(); }else{ Toast.makeText(getApplicationContext(), "sd卡不存在...", Toast.LENGTH_SHORT).show(); } } } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
以上代码就完成了sd卡内部数据的写入和读出...还需要设置的权限就是在AndroidManifest.xml文件内部进行权限设置...
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
这样就完成了在sd卡实现数据的存储....