当前位置:

首页 > 系统应用 > 6.2 数据存储与访问之——SharedPreferences保存用户偏好参数

6.2 数据存储与访问之——SharedPreferences保存用户偏好参数

本文目录

    本节引言: 这一节要说的,是保存用户数据的第二种常见方式:使用SharedPreferences来存储用户偏好参数。像应用里经常会遇到的这类信息——比如是否自动登录、是否记住账号密码、是否只允许在WiFi环境下联网——如果专门为它们上数据库,多少有点“用力过猛”了。说白了,这些都属于用户偏好设置,也

    本节引言:

    这一节要说的,是保存用户数据的第二种常见方式:使用SharedPreferences来存储用户偏好参数。像应用里经常会遇到的这类信息——比如是否自动登录、是否记住账号密码、是否只允许在WiFi环境下联网——如果专门为它们上数据库,多少有点“用力过猛”了。说白了,这些都属于用户偏好设置,也就是一些配置型信息,通常会保存在特定文件中。比如 Windows 里常见的是 ini 文件,J2SE 里则经常用 properties 属性文件和 xml 文件来保存软件配置;到了 Android 里,最常用的轻量级方案就是 SharedPreferences。它本质上也是基于 xml 文件来存储数据,并且用法有点像 Map 集合,按键值对的方式来组织内容;只要调用 SharedPreferences 的 getXxx(name),就能根据键拿到对应的值,用起来确实很顺手。

    1.SharedPreferences使用示例:

    使用流程图:

    实现代码示例:

    运行效果图:

    流程是输入账号密码后点击登录,将信息保存到SharedPreference文件中, 然后重启app,看到数据已经显示在文本框中了

    另外保存后,我们可以在File Expoler打开data/data/<包名>可以看到在shared_prefs目录下 生成了一个xml文件(因为N5没root,这里找了以前的效果图):

    点击导出到桌面可以看到里面的内容:

    代码实现:

    布局文件activity_main.xml的编写:

    
    
    
    
    
    
    

    编写简单的SP工具类:SharedHelper.ja va:

    /**
     * Created by Jay on 2015/9/2 0002.
     */
    public class SharedHelper {
    private Context mContext;
    public SharedHelper() {
        }
    public SharedHelper(Context mContext) {
            this.mContext = mContext;
        }
    //定义一个保存数据的方法
        public void sa ve(String username, String passwd) {
            SharedPreferences sp = mContext.getSharedPreferences("mysp", Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
            editor.putString("username", username);
            editor.putString("passwd", passwd);
            editor.commit();
            Toast.makeText(mContext, "信息已写入SharedPreference中", Toast.LENGTH_SHORT).show();
        }
    //定义一个读取SP文件的方法
        public Map read() {
            Map data = new HashMap();
            SharedPreferences sp = mContext.getSharedPreferences("mysp", Context.MODE_PRIVATE);
            data.put("username", sp.getString("username", ""));
            data.put("passwd", sp.getString("passwd", ""));
            return data;
        }
    }

    最后是MainActivity.ja va实现相关逻辑:

    public class MainActivity extends AppCompatActivity {
    private EditText editname;
        private EditText editpasswd;
        private Button btnlogin;
        private String strname;
        private String strpasswd;
        private SharedHelper sh;
        private Context mContext;
    @Override
        protected void onCreate(Bundle sa vedInstanceState) {
            super.onCreate(sa vedInstanceState);
            setContentView(R.layout.activity_main);
            mContext = getApplicationContext();
            sh = new SharedHelper(mContext);
            bindViews();
        }
    private void bindViews() {
            editname = (EditText)findViewById(R.id.editname);
            editpasswd = (EditText)findViewById(R.id.editpasswd);
            btnlogin = (Button)findViewById(R.id.btnlogin);
            btnlogin.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    strname = editname.getText().toString();
                    strpasswd = editpasswd.getText().toString();
                    sh.sa ve(strname,strpasswd);
                }
            });
        }
    @Override
        protected void onStart() {
            super.onStart();
            Map data = sh.read();
            editname.setText(data.get("username"));
            editpasswd.setText(data.get("passwd"));
        }
    }

    2.读取其他应用的SharedPreferences

    核心: 获得其他app的Context,而这个Context代表访问该app的全局信息的接口,而决定应用的唯一标识 是应用的包名,所以我们可以通过应用包名获得对应app的Context 另外有一点要注意的是:其他应用的SP文件是否能被读写的前提就是SP文件是否指定了可读或者 可写的权限,我们上面创建的是MODE_PRIVATE的就不可以了~所以说你像读别人的SP里的数据, 很难,另外,一些关键的信息,比如密码保存到SP里,一般都是会做加密的,所以只能自己写自己玩~ 等下会讲下常用的MD5加密方法!

    实现流程图:

    代码示例:

    运行效果图:

    代码实现:

    我们读取SP的操作放在MainActivity.ja va中完成,点击按钮后读取SP,并通过Toast显示出来:

    public class MainActivity extends AppCompatActivity {
    private Context othercontext;
        private SharedPreferences sp;
    @Override
        protected void onCreate(Bundle sa vedInstanceState) {
            super.onCreate(sa vedInstanceState);
            setContentView(R.layout.activity_main);
            Button btnshow = (Button) findViewById(R.id.btnshow);
            btnshow.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //获得第一个应用的包名,从而获得对应的Context,需要对异常进行捕获
                    try {
                        othercontext = createPackageContext("com.jay.sharedpreferencedemo", Context.CONTEXT_IGNORE_SECURITY);
                    } catch (PackageManager.NameNotFoundException e) {
                        e.printStackTrace();
                    }
                    //根据Context取得对应的SharedPreferences
                    sp = othercontext.getSharedPreferences("mysp", Context.MODE_WORLD_READABLE);
                    String name = sp.getString("username", "");
                    String passwd = sp.getString("passwd", "");
                    Toast.makeText(getApplicationContext(), "Demo1的SharedPreference存的n用户名为:" + name + "n密码为:" + passwd, Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    3.使用MD5对SharedPreference的重要数据进行加密

    嘿嘿,上面我们这样直接把账号密码保存到sp里,如果没root的手机,别的应用倒无法访问手机, 如果root了,然后数据给其他应用获取到,然后造成了一些后果,这...就不怪我们了,哈哈, 谁叫你root了~,这锅我们不背,的确是这样!但是作为一名有责任心的APP开发人员,我们总不能 这样是吧,我们可以使用一些加密算法对用户密码进行加密,另外我们一般加密的都是用户密码! 下面我们简画个简单的图帮助大家理解下加密的处理的流程:

    1.简单的加密处理流程

    流程图如下:

    流程图解析:

    • Step 1.用户注册账号密码,账号密码校验后(账号是否重复,密码位数 > 6位等), 即账号密码有效,注册成功后,我们提交给服务器的账号,以及本地加密过的密码!
    • Step 2.服务器端将用户提交的账号,加密过的密码保存到服务端的数据库中,也就是服务 端并不会保存我们的明文密码(原始)密码!
    • Step 3.说回客户端,如果注册成功或者登陆成功,你想保存账号密码到SP中,保存的的密码 也需要走一趟加密流程!即明文密码——>加密,再保存!如果不保存,每次请求的时候,明文密码 也要走一趟家里流程,然后拿着加密后的密码来请求服务器!
    • Step 4.服务器验证账号以及加密密码,成功,分配客户端一个session标识,后续客户端可以拿着 这个session来访问服务端提供的相关服务!

    嘿嘿,理解了吧,加密的方法有很多种,小猪也不是这方面的高玩,以前使用过的加密方法是MD5 加密,本节也给大家简单介绍一下这个MD5加密,以及演示下用法~

    2.MD5简单介绍:

    1)MD5是什么鬼?:

    答:MD5,全称 Message Digest Algorithm MD5,中文通常叫“消息摘要算法第五版”。它本质上是一种在计算机安全领域里被广泛使用的散列函数,主要作用是校验消息完整性——这一定义可见于《百度百科》。说得更直白一点,可以把它理解成一种常见的加密处理方式:无论是一个字符串,还是一个文件、压缩包,经过 MD5 处理之后,都会得到一个固定长度为 128bit 的结果,而且这个结果在绝大多数情况下可以看作是基本唯一的。再往下推一步也不难理解:一个十六进制字符需要 4 个 bit 来表示,所以 MD5 最终常见的字符串长度就是 128 / 4 = 32 位。另外,有时也会看到 16 位的 md5,其实并不是另一套算法,只是把 32 位 MD5 码的前八位和后八位去掉了而已。不信的话,可以自己试一下,百度搜索“md5在线解密”,第一个:http://www.cmd5.com/

    2)MD5能破解吗?

    答:MD5不可逆,就是说没有对应的算法,无法从生成的md5值逆向得到原始数据! 当然暴力破解除外,简单的MD5加密后可以查MD5库~

    3)MD5值唯一吗?

    答:不唯一,一个原始数据只对应一个MD5值,但是一个MD5值可能对应多个原始数据!

    3.MD5加密实现例子:

    其实网上有很多写好的MD5的例子,百度或者谷歌一搜一大堆,这里提供下小猪用的MD5加密工具类!

    Md5Util.ja va:

    /**
     * Created by Jay on 2015/9/2 0002.
     */
    public class MD5 {
        public static String getMD5(String content) {
            try {
                MessageDigest digest = MessageDigest.getInstance("MD5");
                digest.update(content.getBytes());
                return getHashString(digest);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return null;
        }
    private static String getHashString(MessageDigest digest) {
            StringBuilder builder = new StringBuilder();
            for (byte b : digest.digest()) {
                builder.append(Integer.toHexString((b >> 4) & 0xf));
                builder.append(Integer.toHexString(b & 0xf));
            }
            return builder.toString();
        }
    }

    MainActivity.ja va直接调用getMD5这个静态方法:

    Log.e("HeHe", MD5.getMD5("呵呵"));
    我们可以看到Logcat上打印出:

    这就是加密过后的呵呵了,我们可以把这串密文拷贝到上面这个md5的在线解密网站:

    嘿嘿,果然,只是这样加密一次,就直接破解了,有点不安全的样子,那就加密100次咯, 就是将加密后的字符串再加密,重复100次,我们在原先的基础上加个加密一百次的方法:

    public static String getMD5x100(String content){
        String s1 = content;
        for(int i = 0;i < 100;i++){
            s1 = getMD5(s1);
        }
        return s1;
    }

    然后调用下,发现打印这个的Log:

    复制界面网站上:

    好的,装B成功~

    4.SharedPreference工具类:

    每次都要自行实例化SP相关的类,肯定很麻烦,这里贴个SP的工具类,大家可以贴到 自己的项目中,工具类来源于鸿洋大神的blog~

    SPUtils.ja va

    package com.jay.sharedpreferencedemo3;
    import android.content.Context;
    import android.content.SharedPreferences;
    import ja va.util.Map;
    /**
     * Created by Jay on 2015/9/2 0002.
     */
    public class SPUtils {
        /**
         * 保存在手机里的SP文件名
         */
        public static final String FILE_NAME = "my_sp";
    /**
         * 保存数据
         */
        public static void put(Context context, String key, Object obj) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
            if (obj instanceof Boolean) {
                editor.putBoolean(key, (Boolean) obj);
            } else if (obj instanceof Float) {
                editor.putFloat(key, (Float) obj);
            } else if (obj instanceof Integer) {
                editor.putInt(key, (Integer) obj);
            } else if (obj instanceof Long) {
                editor.putLong(key, (Long) obj);
            } else {
                editor.putString(key, (String) obj);
            }
            editor.commit();
        }
    /**
         * 获取指定数据
         */
        public static Object get(Context context, String key, Object defaultObj) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
            if (defaultObj instanceof Boolean) {
                return sp.getBoolean(key, (Boolean) defaultObj);
            } else if (defaultObj instanceof Float) {
                return sp.getFloat(key, (Float) defaultObj);
            } else if (defaultObj instanceof Integer) {
                return sp.getInt(key, (Integer) defaultObj);
            } else if (defaultObj instanceof Long) {
                return sp.getLong(key, (Long) defaultObj);
            } else if (defaultObj instanceof String) {
                return sp.getString(key, (String) defaultObj);
            }
            return null;
        }
    /**
         * 删除指定数据
         */
        public static void remove(Context context, String key) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
            editor.remove(key);
            editor.commit();
        }
    /**
         * 返回所有键值对
         */
        public static Map getAll(Context context) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
            Map map = sp.getAll();
            return map;
        }
    /**
         * 删除所有数据
         */
        public static void clear(Context context) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
            editor.clear();
            editor.commit();
        }
    /**
         * 检查key对应的数据是否存在
         */
        public static boolean contains(Context context, String key) {
            SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
            return sp.contains(key);
        }
    }

    5.代码下载:

    SharedPreferenceDemo.zip:下载 SharedPreferenceDemo.zip SharedPreferenceDemo2.zip:下载 SharedPreferenceDemo2.zip SharedPreferenceDemo3.zip:下载 SharedPreferenceDemo3.zip

    本节小结:

    好的,关于Android存储数据的第二种方式:SharedPreference保存用户偏好参数的内容就这么多, 应该可以满足你日常开发使用SP的需求,如果有什么遗漏,欢迎提出,谢谢~

    本文内容来源于网友投稿,如有侵权请联系删除。
    作者最新文章
    系统应用
    相关文章 更多
    win10忘记当前密码了怎么处理完整方法
    win10忘记当前密码了怎么处理完整方法

    Windows 10忘记开机密码如何处理?本文根据账户类型(Microsoft账户/本地账户/PIN)提供官方支持的恢复步骤,包括在线重置、安全问题回答及管理员重置方法,避免数据丢失风险。

    win10更新提示不断弹出如何永久关闭通知
    win10更新提示不断弹出如何永久关闭通知

    Windows 10更新提示频繁弹窗怎么办?本文详解如何通过Windows更新高级选项、系统通知设置及暂停更新功能,精准关闭不必要的重启提醒和横幅通知,同时确保系统安全更新不受影响。适用于家庭及个人用户,区分个人设置与企业策略管理。

    win10家庭版能不能取消开机密码,操作步骤是什么
    win10家庭版能不能取消开机密码,操作步骤是什么

    Win10家庭版如何取消开机密码?本文详解本地账户清空密码步骤及Microsoft账户自动登录设置方法,分析安全风险与例外情况,帮助用户在便捷与安全间做出合理选择。

    win10取消开机密码出现两个登录账户要怎么处理
    win10取消开机密码出现两个登录账户要怎么处理

    解决Win10取消开机密码后登录界面显示两个账户的问题。通过检查账户类型、重新配置netplwiz自动登录及清理多余用户,确保系统正常启动且数据安全。

    win10取消开机密码操作失败是什么原因怎么排查
    win10取消开机密码操作失败是什么原因怎么排查

    遇到Win10无法取消开机密码?可能是Microsoft账户限制、域策略禁止空密码或自动登录未同步。本文详解如何区分账户类型、检查本地安全策略,以及使用PIN码替代传统密码的快速登录方案。

    win10netplwiz没有勾选框该怎么取消开机密码
    win10netplwiz没有勾选框该怎么取消开机密码

    解决Win10运行netplwiz找不到“用户必须输入用户名和密码”勾选框的问题。通过关闭Windows Hello强制登录、检查账户类型及正确填写凭据,实现开机自动进入桌面。适用于个人电脑优化启动体验,注意区分自动登录与删除密码的安全差异。

    win10怎么取消开机密码新手完整操作教程
    win10怎么取消开机密码新手完整操作教程

    新手如何取消Win10开机密码?本文详解区分账户类型、清空本地密码及配置netplwiz自动登录的步骤,厘清PIN码与密码区别,提供安全可行的免密启动方案。

    win10关闭WindowsHello后如何取消开机密码
    win10关闭WindowsHello后如何取消开机密码

    Win10关闭Windows Hello后开机仍要密码?本文详解如何删除PIN码、设置netplwiz自动登录以及清空本地账户密码,解决开机免密登录问题。

    win10取消开机密码要不要关闭屏幕保护密码
    win10取消开机密码要不要关闭屏幕保护密码

    想取消Win10开机密码?先分清是启动登录还是屏保恢复。本文详解如何通过netplwiz设置自动登录,以及如何关闭屏幕保护恢复时的登录验证,同时保留睡眠唤醒的安全设置,确保操作准确且不影响电脑安全。

    win10微软账户如何取消开机密码直接进桌面
    win10微软账户如何取消开机密码直接进桌面

    想在Win10开机时跳过密码直接进入桌面?本文详解Microsoft账户下的PIN设置、本地账户切换及netplwiz自动登录配置,并区分开机验证与锁屏恢复设置,助你安全高效地优化登录体验。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    macOS软件
    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    Mac软件 更多
    photoshop
    photoshop
    Windows、macOS 、 iPad

    Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。

    Blender
    Blender
    Windows、macOS 和 Linux

    Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。

    灵活计算器
    灵活计算器
    macOS/iOS/Android

    灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

    WINDOWS 更多
    3dmax(3ds max)
    3dmax(3ds max)
    Windows

    Autodesk 3ds Max 是一款专业的三维建模、动画与渲染软件,广泛应用于建筑可视化、游戏开发、影视动画、广告设计和产品展示等领域。

    photoshop
    photoshop
    Windows、macOS 、 iPad

    Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。

    Blender
    Blender
    Windows、macOS 和 Linux

    Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。