• 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:   }
  • 相关阅读:
    【LeetCode & 剑指offer刷题】动态规划与贪婪法题13:Coin Change(系列)
    【LeetCode & 剑指offer刷题】动态规划与贪婪法题12:Jump Game(系列)
    【LeetCode & 剑指offer刷题】动态规划与贪婪法题11:121. Best Time to Buy and Sell Stock(系列)
    【LeetCode & 剑指offer刷题】动态规划与贪婪法题10:Longest Increasing Subsequence
    linux安装rabbitmq
    微服务-springboot-读写分离(多数据源切换)
    微服务-springboot-rabbitmq:实现延时队列
    java-NIO-DatagramChannel(UDP)
    java-NIO-FileChannel(文件IO)
    java-NIO-概念
  • 原文地址:https://www.cnblogs.com/mcsm/p/2597741.html
Copyright © 2020-2023  润新知