Android高级编程(笔记)-第6章 数据存储、检索和共享--1--共享Preference

 

三种技术:preference、本地文件和SQLite

一、Android中的数据保存技术:

共享的preference

文件

SQLite数制库

内容提供器

 

共享的preference

 

二、保存简单的应用程序数据

    两种轻量级技术:共享的preference和用来保存活动实例细节的一对事件处理程序

SharedPreference在应用程序中创建命名的键/值映射

    活动提供SaveInstanceState处理程序,参数Bundle代表一个基本的键/值映射,其后这一参数传给OnCreate和onRestoreInstanceState方法处理程序,用以记录活动(Activity)需要的值

1、创建和保存preference

    上下文调用getSharedPreference

    SharedPreference.Editor类:修改一个共享preference。用法:在SharedPreference上调用edit得到一个编辑器对象,保存编辑,只需调用编辑器commit即可。

2、检索共享的Preference

    使用getSharedPreference访问已经保存的共享Preference,通过传递给它希望访问的共享Preference的名称,并使用类型安全的get<type>方法来提取已保存的值

3、保存活动状态

      Activity.getPrefrence():不指定名字,保存不需要和其它组件进行共享的活动信息(如类实例变量)。

如何使用活动的私有共享Preference:

 
   1: protected void saveActivityPreference(){
   2:       // 创建或者检索活动的preference
   3:       SharedPreferences activityPreference = getPreferences(Activity.MODE_PRIVATE);
   4:       //找一个编辑器来修改共享的preference
   5:       SharedPreferences.Editor editor = activityPreference.edit();
   6:       
   7:       //检索View
   8:       TextView myTextView=(TextView)findViewById(R.id.myTextView);
   9:       
  10:       // 在共享的Preference对象中存储新的原语类型
  11:       editor.putString("currentTextValue", myTextVIew.getText().toString());
  12:       //提交修改
  13:       editor.commit();
  14:   }

 

    ⑴ 保存和恢复实例状态

        重写onSaveInstanceState事件处理程序,用其参数Bundle参数来保存实例的值。使用相同的getset方法对共享的preferenct的值进行存储,然后把修改过的Bundle传给超类的处理函数

   1: private static final String TEXTVIEW_STATIC_KEY = "TEXTVIEW_STATIC_KEY";
   2:   @Override
   3:   public void onSaveInstanceState(Bundle outState){
   4:       //检索View
   5:       TextView myTextVIew = (TextView)findViewById(R.id.myTextView);
   6:       //保存它的状态
   7:       outState.putString(TEXTVIEW_STATIC_KEY, myTextView.getText().toString());
   8:       super.onSaveInstanceState(outState);      
   9:   }

        onRestoreInstanceState在一次会话被强制重启时触发,Bundle会传递到其onCreate方法中。下列展示如何从Bundle中提取值,用它来更新活动的实例状态

   1: @Override
   2:   public void onCreate(Bundle icicle) {
   3:     super.onCreate(icicle);
   4:     setContentView(R.layout.preferences);
   5:  
   6:     TextView myTextVIew = (TextView)findViewById(R.id.myTextView);
   7:     
   8:     String text = "";
   9:     if(icicle != null && icicle.containsKey(TEXTVIEW_STATIC_KEY));
  10:     text = icicle.getString(TEXTVIEW_STATIC_KEY);
  11:     
  12:     myTextVIew.setText(text);
  13:     
  14:   }

⑵ 保存To-Do List活动状态

    To-Do List(待办事项表)状态由三种变量组成:

    ·是否添加了新的条目

    ·新条目的输入文本框中存储了哪些文本?

    ·当前选择的条目是什么?

 

   a.首先:添加静态字符串变量作为preference键

   1: // UI State Key Constants
   2:   static final private String TEXT_ENTRY_KEY = "TEXT_ENTRY_KEY";
   3:   static final private String ADDING_ITEM_KEY = "ADDING_ITEM_KEY";
   4:   static final private String SELECTED_INDEX_KEY = "SELECTED_INDEX_KEY";

    b.重写onPause方法,取得私有共享preference的Editor对象

       然后用第1步的键存储所列的实例值

   1: @Override
   2:   protected void onPause(){
   3:     super.onPause();
   4:     
   5:     // Get the activity preferences object.
   6:     SharedPreferences uiState = getPreferences(0);
   7:     // Get the preferences editor.
   8:     SharedPreferences.Editor editor = uiState.edit();
   9:  
  10:     // Add the UI state preference values.
  11:     editor.putString(TEXT_ENTRY_KEY, myEditText.getText().toString());
  12:     editor.putBoolean(ADDING_ITEM_KEY, addingNew);
  13:   
  14:     // Commit the preferences.
  15:     editor.commit();
  16:   }

⑶ 编写retoreUIState方法

   1: @Override
   2:   public void onCreate(Bundle icicle) {
   3:     super.onCreate(icicle);
   4:     ...
   5:     restoreUIState();
   6: }
   7:  
   8: /** Apply the saved UI state */
   9:   private void restoreUIState() {
  10:     // Get the activity preferences object.
  11:     SharedPreferences settings = getPreferences(0);
  12:  
  13:     // Read the UI state values, specifying default values.
  14:     String text = settings.getString(TEXT_ENTRY_KEY, "");
  15:     Boolean adding = settings.getBoolean(ADDING_ITEM_KEY, false);
  16:     
  17:     // Restore the UI to the previous state.
  18:     if (adding) {
  19:       addNewItem();
  20:       myEditText.setText(text);
  21:     }
  22:   }

 

 

⑷ 使用OnSaveInstanceState/onRestoreInstanceState记录选中条目的索引

   1: @Override
   2:   public void onSaveInstanceState(Bundle savedInstanceState) {
   3:     savedInstanceState.putInt(SELECTED_INDEX_KEY, myListView.getSelectedItemPosition());
   4:  
   5:     super.onSaveInstanceState(savedInstanceState);
   6:   }
   7:  
   8:   @Override
   9:   public void onRestoreInstanceState(Bundle savedInstanceState) {
  10:     int pos = -1;
  11:  
  12:     if (savedInstanceState != null)
  13:       if (savedInstanceState.containsKey(SELECTED_INDEX_KEY))
  14:         pos = savedInstanceState.getInt(SELECTED_INDEX_KEY, -1);
  15:  
  16:     myListView.setSelection(pos);
  17:   }
  18:   

4、为地震查看器创建一个preference页

    (1)添加字符串资源,为显示的标签添加新的字符串资源

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Earthquake</string>
<string name="quake_feed">http://earthquake.usgs.gov/eqcenter/catalogs/1day-M2.5.xml</string>
<string name="menu_update">Refresh Earthquakes</string>
<string name="auto_update_prompt">Auto Update?</string>
<string name="update_freq_prompt">Update Frequency</string>
<string name="min_quake_mag_prompt">Minimum Quake Magnitude</string>
<string name="menu_preferences">Preferences</string>
</resources>

    (2)创建新的preferences.xml,布局preferences活动的UI

 

preferences.xml

 

(3)在res/values/arrays.xml文件中创建4个数组

arrays.xml

 

 

(4) 创建preferenceit活动

    重写onCreate,重写第2步的布局,获得复选框和spinner控件的引用,然后调用

populateSpinners存根

   1: public class Preferences extends Activity {
   2:  
   3:   CheckBox autoUpdate;
   4:   Spinner updateFreqSpinner;
   5:   Spinner magnitudeSpinner;
   6:  
   7: @Override
   8:   public void onCreate(Bundle icicle) {
   9:     super.onCreate(icicle);
  10:     setContentView(R.layout.preferences);
  11:  
  12:     updateFreqSpinner = (Spinner)findViewById(R.id.spinner_update_freq);
  13:     magnitudeSpinner = (Spinner)findViewById(R.id.spinner_quake_mag);
  14:     autoUpdate = (CheckBox)findViewById(R.id.checkbox_auto_update);
  15:  
  16:     populateSpinners();
  17:    }
  18:    
  19:     private void populateSpinners() {  }
  20: }

 

(5)用Array Adaper绑定spinner,完成populateSpinners():

   1: private void populateSpinners() {  
   2:       // 填充更新频率
   3:       ArrayAdapter<CharSequence> fAdapter;
   4:       fAdapter = ArrayAdapter.createFromResource(this, R.array.update_freq_options,
   5:                                                  android.R.layout.simple_spinner_item);
   6:       fAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
   7:       updateFreqSpinner.setAdapter(fAdapter);
   8:             
   9:       // 填充最小震级 
  10:          ArrayAdapter<CharSequence> mAdapter;
  11:          mAdapter = ArrayAdapter.createFromResource(this, R.array.magnitude_options,
  12:                                                     android.R.layout.simple_spinner_item);        
  13:       mAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);        
  14:       magnitudeSpinner.setAdapter(mAdapter);
  15:     }

 

(6)创建命名的共享preference,更新onCreate进行检索preference,调用updateUIFromPreferences方法通过对共享的preference使用get<type>检索第一个preference值

   1: SharedPreferences prefs;
   2:   
   3:   public static final String USER_PREFERENCE = "USER_PREFERENCES";
   4:   
   5:   public static final String PREF_AUTO_UPDATE = "PREF_AUTO_UPDATE";
   6:   public static final String PREF_MIN_MAG = "PREF_MIN_MAG";
   7:   public static final String PREF_UPDATE_FREQ = "PREF_UPDATE_FREQ";
   8:  
   9:   @Override
  10:   public void onCreate(Bundle icicle) {
  11:     super.onCreate(icicle);
  12:     setContentView(R.layout.preferences);
  13:  
  14:     updateFreqSpinner = (Spinner)findViewById(R.id.spinner_update_freq);
  15:     magnitudeSpinner = (Spinner)findViewById(R.id.spinner_quake_mag);
  16:     autoUpdate = (CheckBox)findViewById(R.id.checkbox_auto_update);
  17:  
  18:     populateSpinners();
  19:       
  20:     prefs = getSharedPreferences(USER_PREFERENCE, Activity.MODE_PRIVATE);
  21:     updateUIFromPreferences();
  22:    }

 

   1: private void updateUIFromPreferences() {
   2:       boolean autoUpChecked = prefs.getBoolean(PREF_AUTO_UPDATE, false);
   3:       int updateFreqIndex = prefs.getInt(PREF_UPDATE_FREQ, 2);
   4:       int minMagIndex = prefs.getInt(PREF_MIN_MAG, 0);
   5:         
   6:       updateFreqSpinner.setSelection(updateFreqIndex);
   7:       magnitudeSpinner.setSelection(minMagIndex);
   8:       autoUpdate.setChecked(autoUpChecked);
   9:   }

 

(7)在onCreate方法中,添加OK和Cancel按钮的事件处理程序:OK按钮先调用savePreference,然后关闭活动
   1: @Override
   2:   public void onCreate(Bundle icicle) {
   3:     super.onCreate(icicle);
   4:     setContentView(R.layout.preferences);
   5:  
   6:     updateFreqSpinner = (Spinner)findViewById(R.id.spinner_update_freq);
   7:     magnitudeSpinner = (Spinner)findViewById(R.id.spinner_quake_mag);
   8:     autoUpdate = (CheckBox)findViewById(R.id.checkbox_auto_update);
   9:  
  10:         ....................
  11:  
  12:     Button okButton = (Button) findViewById(R.id.okButton);
  13:     okButton.setOnClickListener(new View.OnClickListener() {
  14:       public void onClick(View view) {
  15:         savePreferences();
  16:         Preferences.this.setResult(RESULT_OK);
  17:         finish();
  18:       }
  19:     });
  20:  
  21:     Button cancelButton = (Button) findViewById(R.id.cancelButton);
  22:     cancelButton.setOnClickListener(new View.OnClickListener() {
  23:       public void onClick(View view) {
  24:         Preferences.this.setResult(RESULT_CANCELED);
  25:         finish();
  26:       }
  27:     });
  28:   }  
 
(8)根据UI选项记录当前的preference,存储到共享Preference
 
   1: private void savePreferences() {
   2:       int updateIndex = updateFreqSpinner.getSelectedItemPosition();
   3:       int minMagIndex = magnitudeSpinner.getSelectedItemPosition();
   4:       boolean autoUpdateChecked = autoUpdate.isChecked();
   5:  
   6:       Editor editor = prefs.edit();
   7:       editor.putBoolean(PREF_AUTO_UPDATE, autoUpdateChecked);
   8:       editor.putInt(PREF_UPDATE_FREQ, updateIndex);
   9:       editor.putInt(PREF_MIN_MAG, minMagIndex);
  10:       editor.commit();
  11:   }
(9) 将完成的preference活动添加到程序清单
 
<activity android:name=".Preferences" android:label="Earthquake Preferences"></activity>
 
(10)在Earthquake活动中增加菜单项支持:重写onCreateOptionsMenu
   1: @Override
   2:   public boolean onCreateOptionsMenu(Menu menu) {     
   3:     super.onCreateOptionsMenu(menu);
   4:  
   5:     menu.add(0, MENU_UPDATE, Menu.NONE, R.string.menu_update);
   6:     menu.add(0, MENU_PREFERENCES, Menu.NONE, R.string.menu_preferences);
   7:     
   8:     return true;
   9:   }
(11)修改onOptionsItemSelected,选择菜单项时,显示preference活动
          创建一个Intert,传递给startActivityForResult,这将启动Preference屏幕,并通过onActivityResult处理程序保存Preference时通知Earthquake类
   1: @Override
   2:   public boolean onOptionsItemSelected(MenuItem item) {
   3:     super.onOptionsItemSelected(item);
   4:          
   5:     switch (item.getItemId()) {
   6:       case (MENU_UPDATE): {
   7:         refreshEarthquakes();
   8:         return true; 
   9:       }
  10:       case (MENU_PREFERENCES): {
  11:         Intent i = new Intent(this, Preferences.class);
  12:         startActivityForResult(i, SHOW_PREFERENCES);
  13:         return true;
  14:       }
  15:     } 
  16:     return false;
  17:   }
 

 

(12)启动程序,从菜单中选择Preference

(13)把Preference应用到Earthquake功能中,以上的应用框架已经搭好。

(14)创建updateFromPreferences读取共享Preference,为第一个值创建实例变量

   1: private void updateFromPreferences() {
   2:     SharedPreferences prefs = getSharedPreferences(Preferences.USER_PREFERENCE, Activity.MODE_PRIVATE);
   3:  
   4:     int minMagIndex = prefs.getInt(Preferences.PREF_MIN_MAG, 0);
   5:     if (minMagIndex < 0)
   6:       minMagIndex = 0;
   7:  
   8:     int freqIndex = prefs.getInt(Preferences.PREF_UPDATE_FREQ, 0);
   9:     if (freqIndex < 0)
  10:       freqIndex = 0;
  11:  
  12:     autoUpdate = prefs.getBoolean(Preferences.PREF_AUTO_UPDATE, false);
  13:  
  14:     Resources r = getResources();
  15:     // Get the option values from the arrays.
  16:     int[] minMagValues = r.getIntArray(R.array.magnitude);
  17:     int[] freqValues = r.getIntArray(R.array.update_freq_values);
  18:  
  19:     // Convert the values to ints.
  20:     minimumMagnitude = minMagValues[minMagIndex];
  21:     updateFreq = freqValues[freqIndex];
  22:   }

(15)更新addNewQuake方法,用地震过滤器来检查一个新的地震震级,然后将其添加到列表中

   1: private void addNewQuake(Quake _quake) {  
   2:       if(_quake.getMagnitude()>minimumMagnitude)
   3:       //向我们的地震列表添加新的地震
   4:       earthquakes.add(_quake);
   5:  
   6:       // 把这个改变通知ArrayAdapter
   7:       aa.notifyDataSetChanged();
   8:     }

 

      (16) 重写onActivityResult调用updateFormPreference,在保存了修改后刷新地震

   1: @Override
   2:   public void onActivityResult(int requestCode, int resultCode, Intent data) {
   3:     super.onActivityResult(requestCode, resultCode, data);
   4:  
   5:     if (requestCode == SHOW_PREFERENCES)
   6:       if (resultCode == Activity.RESULT_OK) {
   7:         updateFromPreferences();
   8:         refreshEarthquakes();
   9:       } 
  10:   }

 

   1: @Override
   2:   public void onCreate(Bundle icicle) {
   3:     super.onCreate(icicle);
   4:     setContentView(R.layout.main);
   5:  
   6:     earthquakeListView = (ListView)this.findViewById(R.id.earthquakeListView);
   7:     earthquakeListView.setOnItemClickListener(new OnItemClickListener() {
   8:       public void onItemClick(AdapterView<?> _av, View _v, int _index, long _id) {
   9:         selectedQuake = earthquakes.get(_index);
  10:         showDialog(QUAKE_DIALOG);
  11:       }
  12:     });
  13:  
  14:     aa = new ArrayAdapter<Quake>(getApplicationContext(), android.R.layout.simple_list_item_1, earthquakes);
  15:     earthquakeListView.setAdapter(aa);
  16:  
  17:     loadQuakesFromProvider();
  18:     
  19:     updateFromPreferences();
  20:     refreshEarthquakes();  
  21:   }

 (17)在onCreate中调用updateFormPreference,在活动第一次启动时preference被应用

   1: @Override
   2:   public void onCreate(Bundle icicle) {
   3:     super.onCreate(icicle);
   4:     setContentView(R.layout.main);
   5:  
   6:     earthquakeListView = (ListView)this.findViewById(R.id.earthquakeListView);
   7:     earthquakeListView.setOnItemClickListener(new OnItemClickListener() {
   8:       public void onItemClick(AdapterView<?> _av, View _v, int _index, long _id) {
   9:         selectedQuake = earthquakes.get(_index);
  10:         showDialog(QUAKE_DIALOG);
  11:       }
  12:     });
  13:  
  14:     aa = new ArrayAdapter<Quake>(getApplicationContext(), android.R.layout.simple_list_item_1, earthquakes);
  15:     earthquakeListView.setAdapter(aa);
  16:  
  17:     loadQuakesFromProvider();
  18:     
  19:     updateFromPreferences();
  20:     refreshEarthquakes();  
  21:   }

 

 

 

 

 

 

posted @ 2012-07-18 16:58  庙子  阅读(395)  评论(0编辑  收藏  举报