• android下配置偏好信息的管理


     android下配置偏好信息的管理

    佣工7001

     

           应用程序一般都有这样的需求,为了应用有更好的适应性,有一些参数设置需要独立出来放在配置文件里面。这个配置文件应该是开发的时候就编辑好的设好了默认值,安装后应该可以让用户修改一些设置并保存。程序运行的时候读取这些设置并根据设置不同进行不同的操作。比如windows下程序惯用的INI文件,如果是j2ee项目我们会使用property文件来保存这些参数,那么在android下面如何实现呢?在android中提供了SharedPreference这个类来配置参数设置,书上网上很多例子都是用程序对SharedPreference的读写操作,可是怎样拥有初始设置的值呢?当然可以自己读取资源中的xml文件,然后手动写程序保存到SharedPreference中,可这样太麻烦了一点都不方便、不专业。

            经过我的一番搜索研究,发现最好的方法就是使用Preference管理设置,android sdk已内置了良好的支持,所有的功能都在android.preference这个命名空间中。经学习发现这个preference的管理是和SharedPreference结合实现的,完美的实现了我的需求,并且是实现了和android系统设置中一样的设置管理界面,显得很专业微笑。闲言少叙,下面就具体来看如何使用preference实现配置功能。

            一、建立配置文件。

            在项目res目录下xml目录下(如果没有请建立)建立一个settings.xml的xml文件(文件名不一定叫settings,但是一定要放在xml目录下),文件内容如下:

    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
        android:title="Settings" >
    
        <PreferenceCategory android:key="general" android:title="基本设置">
    			<ListPreference android:key="superman" android:entries="@array/choice"  android:entryValues="@array/choiceId" 
    			    android:dialogTitle="我的最爱" android:summary=""
    			    android:defaultValue="value5" android:title="你选哪个"/>    
    			<CheckBoxPreference android:key="bigman" android:title="我要做大英雄"
                android:defaultValue="true"
                android:summaryOn="唯大英雄能本色,是真名士自风流" android:summaryOff="请君暂上凌烟阁,若个书生万户侯"/>
    			<EditTextPreference
                android:defaultValue="宁可我负天下人,不可天下人负我!"
                android:key="maxim"
                android:summary="有了信仰就要干,不要无志者常立志"
                android:title="我最爱的格言" />    
          <EditTextPreference
                android:defaultValue="星球大战"
                android:key="favoriteFilm"
                android:summary="没有最好,只有更好"
                android:title="我最爱的电影" /> 
        </PreferenceCategory>
        <PreferenceCategory android:key="advanced" android:title="高级设置">
        <PreferenceScreen android:key="basicSettings" android:title="高级设置" android:summary="点击进入高级设置" >
            <CheckBoxPreference android:key="checkVersion" android:title="自动更新"
                android:defaultValue="false"
                android:summaryOn="程序将每隔一段时间自动检查新版本" android:summaryOff="自动更新已关闭"/>
            <EditTextPreference
                android:defaultValue="1"
                android:key="checkVersionTime"
                android:summary=""
                android:title="检查新版本间隔时间(天)" />
            <EditTextPreference
                android:defaultValue="http://192.168.0.99:8008/crx/xtgl.User"
                android:key="url"
                android:summary=""
                android:title="URL" />
    
            <EditTextPreference
                android:defaultValue="http://60.29.99.76:8008/crx/xtgl.Unit?__fn_=initdata"
                android:key="url1"
                android:summary=""
                android:title="URL2" />
    
            <EditTextPreference
                android:defaultValue="htt2.p://192.168.0.100:8558/crx/manage.HistVote"
                android:key="URL3"
                android:summary=""
                android:title="URL3" />
            
        </PreferenceScreen>
    	</PreferenceCategory>
    </PreferenceScreen>

    
    

             文件的根元素就是PreferenceScreen,望文生义,就是一个屏幕显示的配置内容,并且可以嵌套使用。PreferenceScreen下面还可以分类,这就是PreferenceCategory元素,并且PreferenceCategory元素下面同样可以嵌套PreferenceScreen元素(其实PreferenceScreen就是PreferenceCategory的子类)。详细的配置内容可用的元素有EditTextPreference,CheckBoxPreference,ListPreference,Preference,RingtongPreference......

            从上面的配置文件中可以看出一个Preference配置项目主要拥有的属性。其中Key为这个PreferenceID,设置了才可以在代码中引用,Title是显示的标题,Summary是显示在标题下的文字介绍,Dependency是指依赖的其他配置项(注:一般在Dependency中填写一个CheckBoxPreferenceKey,这样就会在填写的那个CheckBoxPreference勾选时当前这个Preference才可用),Default Value为初始值,等等。其他的请大家自己看sdk,在这里就不赘述了。

            值得一提的就是ListPreference的使用稍微复杂一些,ListPreference除了继承自Preference的属性外,还有自己ListPreference的属性和继承自DialogPreference的属性。其中属于ListPreference的属性有两个:Entries填的为一个字符串数组,是列表显示出来的值(用户看到的说明文字),而Entry Values是实际要保存的值对应的字符串数组。DialogPreference只要填一个Dialog title标题和一个取消按钮显示的字即可。下面建立两个String array供ListPreference的选择对话框使用,在res/values目录下建立一个新的myarrays.xml文件(文件名随便),内容如下.

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string-array name="choice">
            <item >超人</item>
            <item >蜘蛛侠</item>
            <item >夜魔侠</item>
            <item >青蜂侠</item>
            <item >蝙蝠侠</item>
            <item >闪电侠</item>
            <item >钢铁侠</item>
            <item >超胆侠</item>
            <item >绿灯侠</item>
        </string-array>
        <string-array name="choiceId">
            <item >value1</item>
            <item >value2</item>
            <item >value3</item>
            <item >value4</item>
            <item >value5</item>
            <item >value6</item>
            <item >value7</item>
            <item >value8</item>
            <item >value9</item>
        </string-array>
        
    </resources>
    好了,我们的前期准备已经搞定了。

           二、读取配置内容。

           配置信息已经建好了,下面就是读取了,怎么读取呢?看到网上的解决方法很简单,就是得到默认的SharedPreference,然后按照Preference的key值读取,好的,马上试验:在Activity中添加一个按钮BtnTestConfig,设置OnClick事件如下:

    OnClickListener onBtnTestConfig = new OnClickListener() {
    		public void onClick(View v) {
    			String s = "not read!";
    			IndexActivity me = IndexActivity.this;
    			SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(me);
    			try {
    				s = sp.getString("favoriteFilm", s);
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    			DialogUtil.ShowMsgDlg(IndexActivity.this, String.valueOf(s));
    		}
    	};
    可是一运行发现,显示的是程序中给出的默认值,根本不是配置写的“星球大战”!咋回事儿呢,老办法google一下,发现有说要用XmlResourceParser自己解析XML,可是这就有违初衷了!不行再搜,终于在老外哪里找到了,原来android不会自动将你的Preference配置同步到SharedPreference中,所以需要用到PreferenceManager.setDefaultValues(Context context, int resId, boolean readAgain)方法,修改程序如下:
    OnClickListener onBtnTestConfig = new OnClickListener() {
    		public void onClick(View v) {
    			String s = "not read!";
    			IndexActivity me = IndexActivity.this;
    			PreferenceManager.setDefaultValues(IndexActivity.this, R.xml.settings, true);
    			SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(me);
    			
    			try {
    				s = sp.getString("favoriteFilm", s);
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    			DialogUtil.ShowMsgDlg(IndexActivity.this, String.valueOf(s));
    		}
    	};
    再次运行,ok,终于读到了!这里注意PreferenceManager.setDefaultValues方法的第三个参数readAgain,false表示只会执行一次,也就是说SharedPreference已经同步过一次,此函数就不会再执行了,这样如果在调试阶段你会发现新增加的配置项目就读不到了(打开设置界面编辑后是可以的),所以调试时最好用true。当然这里只是试验,在实际程序中,最好放在主Activity中执行这个函数。另外,readAgain设为true,不会覆盖已经存在于SharedPreference中的配置值,不会造成用户修改的配置丢失。

    注意,如果你想清除修改的配置,那么在你要这样

    PreferenceManager.getDefaultSharedPreferences(Context context),之后调用
    PreferenceManager.setDefaultValues(Context context, int resId, boolean readAgain),并且readAgain设为true)
           三、实现配置管理界面。

           到现在,Preference已经建立好并且可以读取了,那么怎么实现用户修改Preference设置呢?这个就更简单了,新建立一个Activity并继承PreferenceActivity,

    public class MyPreference extends PreferenceActivity

    然后再onCreate函数中这样写:

    @Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		this.addPreferencesFromResource(R.xml.settings);
    	}
    然后要做的就是在主界面中添加菜单或按钮调用这个Activity(这个就赘述了),怎么样,是不是和系统的设置界面一样漂亮。


             四、更完美的设置界面。

             试了试,搞好的Preference界面,忽然发现了还有一个缺点,每个配置项目下面的Summary信息都是固定的,如果能够显示用户的当前设置那就完美了。废话少说还是网上学习去,过程不必细说,结果发现还真没有方便的手段可用。没办法,只能程序代码实现。所用技术就是Perference.setSummary这个函数。思想就是在初始化的时候,更据当前配置内容,遍历配置项设置summary内容,然后注册SharedPreference的OnSharedPreferenceChangeListener事件监听配置项的变化,随时更新已变化项目的summary信息。

            由于需要注册OnSharedPreferenceChangeListener事件,所以我们的Activity还要实现OnSharedPreferenceChangeListener这个接口。

    public class MyPreference extends PreferenceActivity implements OnSharedPreferenceChangeListener {
            然后添加三个方法:
    /**
    	 * Set the summaries of all preferences
    	 */
    	private void initSummaries(PreferenceGroup pg) {
    		for (int i = 0; i < pg.getPreferenceCount(); ++i) {
    			Preference p = pg.getPreference(i);
    			if (p instanceof PreferenceGroup)
    				this.initSummaries((PreferenceGroup) p); // recursion
    			else
    				this.setSummary(p);
    		}
    	}
    
    	/**
    	 * Set the summaries of the given preference
    	 */
    	private void setSummary(Preference pref) {
    		// react on type or key
    		if (pref instanceof ListPreference) {
    			ListPreference listPref = (ListPreference) pref;
    			listPref.setSummary(listPref.getEntry());
    		}
    		if (pref instanceof EditTextPreference) {
    			EditTextPreference etp = (EditTextPreference) pref;
    			etp.setSummary(etp.getText());
    		}
    
    	}
    
    	/**
    	 * used to change the summary of a preference
    	 */
    	public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
    		Toast.makeText(this, "preference changed! " + key, 3000);
    		Preference pref = findPreference(key);
    		this.setSummary(pref);
    	}

          最后在onCrate方法中添加两行代码:
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	this.addPreferencesFromResource(R.xml.settings);
    	this.getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
          this.initSummaries(this.getPreferenceScreen());
    }
    ok,打完收工,运行起来再看效果:


    怎么样,堪称完美吧。吐舌头下面试试我们的ListPreference,选择一个新的英雄:

     

    选择完成后,再看Preference管理界面,提示信息已变为“夜魔侠”一切ok。

  • 相关阅读:
    iterm2 Mac 常用快捷键
    软件测试:测试方法
    maccms(苹果cms)采集过程报错--MySQL server has gone away错误的解决办法
    ArrayLIst的使用
    hashmap的使用
    hashset机LinkedHashSet的使用
    java集合Collection总结
    maxPostSize属性改变tomcat的post请求的请求体大小设置
    postman中 form-data、x-www-form-urlencoded、raw、binary的区别
    用synchronized关键字及concurrent.locks解决线程并发问题
  • 原文地址:https://www.cnblogs.com/dajianshi/p/2827108.html
Copyright © 2020-2023  润新知