一.存储方式分类:SharedPreferences存储

二.SharedPreferences存储

1.特点

①存储单一数据,例如数值,字符串,布尔

②文件:/date/date/包名/shared_prefs/xxx.xml: value

③以键值对的形式存储

④可以设置不被其他应用操作

2.API

(1)SharedPreferences

①获取实例context.getSharedPreferences():

1)name 存储文件名; 2)mode 操作模式:MODE_PRIVATE不能被别的应用访问,覆盖模式;MODE_APPEND不能被别的应用访问,追加模式;

②启动编辑器:edit():返回Editor

③读取Value:1)getString(key,defValue 缺省值) 2)getAll( ) 返回所有键值对的 Map集合

(2)Editor

①存放数据:1)putString(key,value) 2)putLong(key,value) 3)putInt 4)putFloat 5)putBoolean 6)putStringSet

②提交存储

③clear() 清除

④remove(String key) 移除指令key的键值对

下面请允许我盗一张图

下面开始我的表演

看样子中午还是要休息一下,打疲劳战队身体没好处,而且写的代码质量也不高!

场景一

首先我要实现的功能就是简单的注销用户,当然方法有很多,你可以通过EventBus或者RXBus注册订阅者然后发布一个事件出去,另外一种就是通过后台移除session,清除当前的sesssionid 因为相信大家都知道,客户端只有一个Cookie,Cookie对应服务端Session的key,首先登录的时候服务端返回一个sessionid给我然后我通过sp把拿到的SessionId保存起来,然后在点击退出当前用户的时候把之前登录的SessionId提交过去与服务端那边对比,如果对比一致说明我已经登录过了,然后这时候服务端移除session,返回给我,提示成功退出!

听起来好像思路有点清晰,下面开始我的表演Action

因为我这边提交的都是json格式的数据下面是点击到登录按钮提交的json数据这时候服务器给我返回sid

        Gson gson = new Gson();
        final HashMap<String, String> params = new HashMap<>();
        params.put("username", "18388483434");
        params.put("pass", "123456");
        final String strEntity = gson.toJson(params);
        RequestBody body = RequestBody.create(MediaType.parse("application/json;charset=UTF-8"), strEntity);
        AccountService account = RetrofitApiManager.getInstance().getService(AccountService.class);
        Call<LoginResponse> call = account.login(body);
        final String sessionId=null;
        call.enqueue(new Callback<LoginResponse>() {
            @Override
            public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
                if (response.isSuccessful()) {
                    if (sp == null) {
                        sp = getSharedPreferences("exitsid",MODE_PRIVATE);
                    }
                    SharedPreferences.Editor editor = sp.edit();
                    //sessionid
                    editor.putString("sid", sessionId);
                    //异步提交

                    Toast.makeText(LoginActivity.this,  response.body().getMessage(), Toast.LENGTH_SHORT).show();
//                    Log.i(TAG, "onResponse: " + response.body().getCode() + response.body().getMessage());
                    startActivity(new Intent(LoginActivity.this, MainActivity.class));
                    editor.apply();
                }
            }

            @Override
            public void onFailure(Call<LoginResponse> call, Throwable t) {
                Log.e(TAG, "onFailure: " + t.getMessage());

            }
        });

登录抓包信息如下Fiddler

请求的接口地址因为这里提交的是json数据所以这里添加一个请求头信息,如果你自己觉得太死板,请自定义拦截器,这个没有问题,根据自己的需求来。

    @Headers("Content-type:application/json;charset=UTF-8")
    @POST("xxx/login")
    Call<LoginResponse> login(@Body RequestBody body);

下面是我的响应bean我这里直接GsonFormat生成

package com.visoport.medicine.http.api.response;

/**
 * 登录服务器返回LoginResponse
 */

public class LoginResponse {

    private int code;
    private DataBean data;
    private String message;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public DataBean getData() {
        return data;
    }

    public void setData(DataBean data) {
        this.data = data;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public static class DataBean {

        private String sid;

        public String getSid() {
            return sid;
        }

        public void setSid(String sid) {
            this.sid = sid;
        }
    }
}

下面是注销用户

请求接口loginout

 //退出当前用户
    @Headers("Content-type:application/json;charset=UTF-8")
    @POST("xxx/login/logout")
    Call<ExitUserResponse> logout(@Body RequestBody body);

服务端响应的bean跟上面的LoginResponse一致同样是GsonFormat生成


/**
 * 退出登录
 */

public class ExitUserResponse {

    /**
     * code : 1200
     * data : {"sid":"67b4edd5346c447afe7b9cd0ef"}
     * message : 成功退出
     */

    private int code;
    private DataBean data;
    private String message;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public DataBean getData() {
        return data;
    }

    public void setData(DataBean data) {
        this.data = data;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public static class DataBean {

        private String sid;

        public String getSid() {
            return sid;
        }

        public void setSid(String sid) {
            this.sid = sid;
        }
    }
}

然后点击退出按钮 代码很乱后期整理

              final String sessionId;
                if (sp == null) {
                    sp = getSharedPreferences("exitsid",MODE_PRIVATE);
                }
                //后面是默认值defaultvalue
                sessionId = sp.getString("sid", "");
                Gson gson = new Gson();
                final HashMap<String, String> params = new HashMap<>();
                params.put("sid", sessionId);
                Log.i(TAG, "onClick: "+sessionId);
                String strEntity = gson.toJson(params);
                RequestBody body = RequestBody.create(MediaType.parse("application/json;charset=UTF-8"), strEntity);
                AccountService account = RetrofitApiManager.getInstance().getService(AccountService.class);
                Call<ExitUserResponse> call = account.logout(body);
                call.enqueue(new Callback<ExitUserResponse>() {
                    @Override
                    public void onResponse(Call<ExitUserResponse> call, Response<ExitUserResponse> response) {
                        if(response.isSuccessful())
                        {
                            Toast.makeText(SettingActivity.this,response.body().getMessage(),Toast.LENGTH_SHORT).show();
                            startActivity(new Intent(SettingActivity.this,LoginActivity.class));
                        }
                    }
                    @Override
                    public void onFailure(Call<ExitUserResponse> call, Throwable t) {
                        Toast.makeText(SettingActivity.this,t.getMessage(),Toast.LENGTH_SHORT).show();
                    }
                });

我去,什么鬼,缺少参数,什么参数,为什么会这样,不就是一个sessionid吗?好吧我承认我菜,那断点试试,工欲善其事,必先利其器,那就debug走起不好意思debug今天出了点问题,哈哈!

其实就是自己不小心把那句代码注释掉了手贱!

String sessionId = response.body().getData().getSid();

因为之前的sessionId初始化就是null你怎么可能拿得到吗?后面的读取时没有问题的!狠狠的给自己一巴掌!

final String sessionId=null;

下面直接看最后的表演图

总结:

1、 还是基本功好扎实,首先了解sp简单用法包括存储 写入文件 以及读取文件等

2、出现问题学会debug慢慢调试 看程序的走势进一步找出问题所在

3、必要的时候使用抓包神器Fildder那么问题迎刃而解

[置顶] Android 关于SP读取与存储正确打开方式?的更多相关文章

  1. [置顶] Android开发笔记(成长轨迹)

    分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...

  2. [置顶] Android应用开发之版本更新你莫愁

    传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 今天我们学习如何实现Android应用的自动更新版本功能,这是在各种语言编写的应用中都 ...

  3. [置顶] Android 状态栏那些小坑?

    背景:因为之前老板上次问我我们的app能不能自定义上面的状态栏我说可以啊!当时没管,今天试了下果然很多坑,之前github上也有很多大佬写了一个开源库有兴趣的可以点进去看下支持DrawLayout沉侵 ...

  4. [置顶] Android系统五大布局详解Layout

    我们知道Android系统应用程序一般是由多个Activity组成,而这些Activity以视图的形式展现在我们面前,视图都是由一个一个的组件构成的.组件就是我们常见的Button.TextEdit等 ...

  5. 【Android开发笔记】返回上层Activity的正确打开方式

    技术支持 http://stackoverflow.com/questions/12276027/how-can-i-return-to-a-parent-activity-correctly 首先, ...

  6. [置顶] android之存储篇_SQLite数据库_让你彻底学会SQLite的使用

    SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么. 例如:可以在Integer类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中 ...

  7. [置顶] Android开发之ProcessState和IPCThreadState类分析

    在Android中ProcessState是客户端和服务端公共的部分,作为Binder通信的基础,ProcessState是一个singleton类,每个 进程只有一个对象,这个对象负责打开Binde ...

  8. [置顶] Android开发之MediaPlayerService服务详解(一)

    前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState.ProcessState负责打开Binder 驱动,每个进程只有一个.而 IPCThre ...

  9. Android:Xml(读取与存储)

    1.读取XML文件 参数xml是建含xml数据的输入流,List<Person> persons用于存储xml流中的数据. XmlPullParser类的几个方法:next(),nextT ...

随机推荐

  1. Java 线程池Future和FutureTask

    Future表示一个任务的周期,并提供了相应的方法来判断是否已经完成或者取消,以及获取任务的结果和取消任务. Future接口源码: public interface Future<V> ...

  2. maven 环境变量配置问题 cmd窗口报mvn -v不是内部或者外部的命令

    早上整了一早上maven环境问题,配置的环境变量  系统变量 MAVEN_HOME  C:\JavaTools\apache-maven-3.3.9 本机maven路径,Path变量中编辑,引用的是; ...

  3. AVL模板

    感谢此博客 #include <bits/stdc++.h> #define pb push_back #define mp make_pair #define de(x) cout &l ...

  4. Python学习札记(十四) Function4 递归函数 & Hanoi Tower

    reference:递归函数 Note 1.在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. eg.计算阶乘: #!/usr/bin/env python3 def ...

  5. codevs 1540 银河英雄传说 并查集

    1540 银河英雄传说 2002年NOI全国竞赛  时间限制: 1 s  空间限制: 256000 KB       题目描述 Description 公元五八○一年,地球居民迁移至金牛座α第二行星, ...

  6. Quartz(自动任务)中的触发器Trigger

    1.Quartz中的触发器TriggerJob 包含了要执行任务的逻辑,但是 Job 对何时该执行却一无所知.这个事情留给了 Trigger.Quartz Trigger 继承了抽象的 org.qua ...

  7. wireshark初学者使用

    介绍 Wireshark是一款网络封包分析软件,截取网络封包,显示其封包的详细信息.日常工作中用的比较多.在使用wireshark之前须了解常用的网络协议.如:tcp,http,ip,udp等.(其实 ...

  8. webstrom提示不见了

    今天做项目时候,不知道怎么搞的我的神编辑器webstrom没有了代码提示!!! 重启软件.重启电脑甚至卸载重装都不行,研究了半天终于知道问题出在了哪: 后来我发现在Webstorm的菜单[File]里 ...

  9. fwrite的文件缓冲同步到磁盘

    这是个小细节. 用fwrite写文件的时候,我发现刷新文件夹,对应文件大小一直是0. 网上有一篇博客写得比较完善http://blog.csdn.net/sctq8888/article/detail ...

  10. UVA-12661 Funny Car Racing (dijkstra)

    题目大意:一张有向图,问从起点到终点的最快时间.不过边有点特殊,从u到v的边没开放a秒就关闭b秒. 题目分析:dijkstra算法即可.在从u走到v的时候要注意一下时间. 代码如下: # includ ...