声明:学习的书籍《Android应用开发揭秘》,这里记录学习该书籍的日志,引用的相关代码与总结描述,没有商业的用途,完全是自我学习的一个记录,刚刚学习不可避免会出现很多问题,若是有错误还请大家多多批评。
学习完基本的控件与布局之后,我跳过了游戏编程的章节,直接开始了android关于数据的操作的学习,游戏编程准备放到后面学习,而学习完基本的控件以及相关事件操作之后,按照学习Web开发的流程,也就是牵涉到了数据操作的数据,包括文件,网络资源以及数据库操作,这块内容,自己反复学习了好几遍因为毕竟每个应用程序都不是独立存在的,数据操作不可避免。废话不说了,开始吧。
一、数据存储之SharedPreferences
对于SharedPreferences的理解,我个人认为就是针对一个程序的init配置文件,也可以理解为我们web开发中得cookie。它存储的方式是键值对的方式进行存储的,而且Android中SharedPreferences也提供了各种数据类型的get方法。注意,SharedPreferences是一个接口,而且一般都是通过getPreferences方法获取Preferences对象。通过Preferences对象的edit()方法获取编辑对象。
// 取得活动的preferences对象. SharedPreferences uiState = getPreferences(0); // 取得编辑对象 SharedPreferences.Editor editor = uiState.edit();
通过编辑对象可以对里面的数据进行更新与维护。
实例分析:该程序是个音乐播放程序,若是在按照返回键退出程序时音乐还在播放,请保存当前音乐的状态,下次启动时音乐状态就是开启的。
音乐播放类MIDIPlayer关键代码:
public MediaPlayer playerMusic = null; private Context mContext = null; public MIDIPlayer(Context context){ mContext = context; } /* 播放音乐 */ public void PlayMusic(){ /* 装载资源中的音乐 */ playerMusic = MediaPlayer.create(mContext, R.raw.start); /* 设置是否循环 播放*/ playerMusic.setLooping(true); try{ playerMusic.prepare();//准备同步,无返回值 }catch (IllegalStateException e){ e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } playerMusic.start(); } /* 停止并释放音乐 */ public void FreeMusic(){ if (playerMusic != null){ playerMusic.stop(); playerMusic.release(); } }
而SharedPreferencesActivity类关键代码:
public void onCreate(Bundle savedInstanceState){ . . . . . . mMIDIPlayer = new MIDIPlayer(this); // 取得活动的preferences对象. SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE); // 取得值. mbMusic = settings.getBoolean("bmusic", false); if (mbMusic){ mTextView.setText("当前音乐状态:开"); mbMusic = true; mMIDIPlayer.PlayMusic(); }else{ mTextView.setText("当前音乐状态:关"); } } public boolean onKeyDown(int keyCode, KeyEvent event){ if (keyCode == KeyEvent.KEYCODE_BACK){ /* 这里我们在退出时保存数据 */ // 取得活动的preferences对象. SharedPreferences uiState = getPreferences(0); // 取得编辑对象 SharedPreferences.Editor editor = uiState.edit(); editor.putBoolean("bmusic", mbMusic); // 添加值 // 提交保存 editor.commit(); if ( mbMusic ){ mMIDIPlayer.FreeMusic(); } this.finish(); return true; } return super.onKeyDown(keyCode, event); }
【扩展学习】
这里需要强调的是:多个程序之间是不能直接共享Preferences数据的。
1. haredPreferences的文件实际是存储在一个文件中,如下图,切换到DDMS视图,
每在模拟器中安装一个项目,对应在data/data目录下产生一个文件夹,若是使用SharedPreferences就会有一个shared_prefs文件夹,
对于本程序对应的SharedPreferencesActivity.xml 内容为:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <boolean name="bmusic" value="true" /> </map>
2 SharedPreferences相关API介绍
内部类
interface SharedPreferences.Editor——于修改SharedPreferences对象设定值的接口。
interface SharedPreferences.OnSharedPreferenceChangeListener ——接口定义一个用于在偏好设定(shared preference)改变时调用的回调函数。
公共方法
public abstract boolean contains (String key) ——判断preferences是否包含一个preference。
参数:key 想要判断的preference的名称
返回值:Peferences中存在preference,则返回true,否则返回false。
public abstract SharedPreferences.Editor edit ()
针对preferences创建一个新的Editor对象,通过它你可以修改preferences里的数据,并且原子化的将这些数据提交回SharedPreferences对象。(译者注:原子化——作为一个整体提交,原子性)
注意:如果你想要在SharedPreferences中实时显示,刚通过Editor对象进行的修改,那么你必须调用commit()方法。
返回一个SharedPreferences.Editor的新实例,允许你修改SharedPreferences对象里的值。
public abstract Map<String, ?> getAll ()——取得preferences里面的所有值,返回一个map,其中包含一列preferences中的键值对
异常:空指针异常(NullPointerException)
public abstract boolean getBoolean (String key, boolean defValue)——从preferences中获取一个boolean类型的值。
参数:key获取的preference的名称
defValue 当此preference不存在时返回的默认值
返回值:如果preference存在,则返回preference的值,否则返回defValue。如果使用此名称的preference不是一个boolean类型,则抛出ClassCastException。
public abstract float getFloat (String key, float defValue)
public abstract int getInt (String key, int defValue)
public abstract long getLong (String key, long defValue)
public abstract String getString (String key, String defValue)
public abstract void registerOnSharedPreferenceChangeListener (SharedPreferences.OnSharedPreferenceChangeListener listener)
注册一个回调函数,当一个preference发生变化时调用。
public abstract void unregisterOnSharedPreferenceChangeListener (SharedPreferences.OnSharedPreferenceChangeListener listener)
注销一个之前(注册)的回调函数
二、数据存储之Files
有的程序需要把数据中保存到相应的文件中,但是要注意的事文件在多个程序之间也是不能共享的。文件存储数据可以openFileOutput方法打开一个文件进行操作。
实例分析:与上面SharedPreferences例子效果一样。
关键源码:
void load(){ /* 构建Properties对对象 */ Properties properties = new Properties(); try{ /* 开发文件 */ FileInputStream stream = this.openFileInput("music.cfg"); /* 读取文件内容 */ properties.load(stream); }catch (FileNotFoundException e){ return; }catch (IOException e){ return; } /* 取得数据 */ mbMusic = Boolean.valueOf(properties.get("bmusic").toString()); } /* 保存数据 */ boolean save(){ Properties properties = new Properties(); /* 将数据打包成Properties */ properties.put("bmusic", String.valueOf(mbMusic)); try{ FileOutputStream stream = this.openFileOutput("music.cfg", Context.MODE_WORLD_WRITEABLE); /* 将打包好的数据写入文件中 */ properties.store(stream, ""); }catch (FileNotFoundException e){ return false; }catch (IOException e){ return false; } return true; }
【扩展学习】
使用Files方式存储数据,同样会在对应data/data目录下面的files文件下也有相关的文件来存储数据,
Music.cfg的文件内容为:
# #Wed Nov 02 10:06:38 GMT+00:00 2011 bmusic=true
三、数据存储之Web数据操作
很多程序都是通过网络来把数据等信息存储到服务上,同样从服务器上读取相关的数据到自己。最典型的如,手机的邮件的收发,当然要使用网络,必先保证手机的网络是连接上。
这里我就在模拟器下配置了163邮箱的绑定,左图效果图,中间图为接受服务器设置,右图为外发服务器设置。
下面两个例子分别是写数据与取数据,
1. 从发送邮件功能(写数据)
关键源码:
public boolean onKeyDown(int keyCode, KeyEvent event){ if(keyCode == KeyEvent.KEYCODE_BACK){ //退出应用程序时保存数据 //发送邮件的地址 Uri uri = Uri.parse("mailto:[email protected]"); //创建Intent Intent intent = new Intent(Intent.ACTION_SENDTO,uri); //设置邮件的主题 intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "数据备份"); //设置邮件的内容 intent.putExtra(android.content.Intent.EXTRA_TEXT, "本次计数:"+miCount); startActivity(intent); this.finish(); return true; } return super.onKeyDown(keyCode, event); }
效果图:
2. 从网页获取数据
为了测试从WEB上获取数据,这里我搭建了一个简单TestWeb的Web项目,并用Tomcat发布,在IE上运行,其中在项目根目录下按照数据例子,放了一个android.txt文件。
关键源码:
String myString = null; try{ /* 定义我们要访问的地址url */ URL uri = new URL("http://192.168.8.64:8080/TestWeb/android.html"); /* 打开这个url连接 */ URLConnection ucon = uri.openConnection(); /* 从上面的链接中取得InputStream */ InputStream is = ucon.getInputStream(); BufferedInputStream bis = new BufferedInputStream(is); ByteArrayBuffer baf = new ByteArrayBuffer(100); int current = 0; /* 一直读到文件结束 */ while ((current = bis.read()) != -1){ baf.append((byte) current); } myString = new String(baf.toByteArray()); }catch (Exception e){ myString = e.getMessage(); } /* 将信息设置到TextView */ tv.setText(myString);
程序运行效果图:
【扩展学习】:
(1)、android访问网络资源必须要有:
<uses-permission android:name="android.permission.INTERNET" />
不然运行会提示:
Permission denied
(2)、
/* 定义我们要访问的地址url */
URL uri = new URL("http://192.168.8.64:8080/TestWeb/android.txt");
/* 打开这个url连接 */
URLConnection ucon = uri.openConnection();
其中若是本地机器,也不能用localhost或者127.0.0.1,不然会连接不上
(3)、测试访问html文件android.html
<html> <head>头部内容</head> <body> 内容信息 </body> </html>
android获取时,获取时html的源码而不是内容,因为他没有解析器,而且会是乱码。
以上数据存储就先学到这里,下一篇文章主要是针对数据库的操作。