[置顶] Android 关于SP读取与存储正确打开方式?
一.存储方式分类: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读取与存储正确打开方式?的更多相关文章
- [置顶] Android开发笔记(成长轨迹)
分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...
- [置顶] Android应用开发之版本更新你莫愁
传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 今天我们学习如何实现Android应用的自动更新版本功能,这是在各种语言编写的应用中都 ...
- [置顶]
Android 状态栏那些小坑?
背景:因为之前老板上次问我我们的app能不能自定义上面的状态栏我说可以啊!当时没管,今天试了下果然很多坑,之前github上也有很多大佬写了一个开源库有兴趣的可以点进去看下支持DrawLayout沉侵 ...
- [置顶] Android系统五大布局详解Layout
我们知道Android系统应用程序一般是由多个Activity组成,而这些Activity以视图的形式展现在我们面前,视图都是由一个一个的组件构成的.组件就是我们常见的Button.TextEdit等 ...
- 【Android开发笔记】返回上层Activity的正确打开方式
技术支持 http://stackoverflow.com/questions/12276027/how-can-i-return-to-a-parent-activity-correctly 首先, ...
- [置顶] android之存储篇_SQLite数据库_让你彻底学会SQLite的使用
SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么. 例如:可以在Integer类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中 ...
- [置顶] Android开发之ProcessState和IPCThreadState类分析
在Android中ProcessState是客户端和服务端公共的部分,作为Binder通信的基础,ProcessState是一个singleton类,每个 进程只有一个对象,这个对象负责打开Binde ...
- [置顶] Android开发之MediaPlayerService服务详解(一)
前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState.ProcessState负责打开Binder 驱动,每个进程只有一个.而 IPCThre ...
- Android:Xml(读取与存储)
1.读取XML文件 参数xml是建含xml数据的输入流,List<Person> persons用于存储xml流中的数据. XmlPullParser类的几个方法:next(),nextT ...
随机推荐
- 20145335《java程序设计》第10周学习总结
20145335郝昊 <Java程序设计>第10周学习总结 教材学习内容总结 网络编程 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的 ...
- Windows下如何安装python第三方库lxml
lxml是个非常有用的python库,它可以灵活高效地解析xml,与BeautifulSoup.requests结合,是编写爬虫的标准姿势. 参考 Windows下如何安装python第三方库lxml ...
- Qt大小端
转:http://blog.csdn.net/usownh/article/details/42614185 大端模式和小端模式是计算机中经常涉及到的两种字节序,也有大端对齐.小端对齐.大尾.小尾等叫 ...
- 戴尔服务器使用omreport(OMSA)查看监控硬件信息
安装OMSA wget -q -O - http://linux.dell.com/repo/hardware/latest/bootstrap.cgi | bash yum install -y n ...
- [Deep Learning] 神经网络基础【转】
本文转载自:http://www.cnblogs.com/maybe2030/p/5597716.html 阅读目录 1. 神经元模型 2. 感知机和神经网络 3. 误差逆传播算法 4. 常见的神经网 ...
- 混合开发的大趋势之一React Native之页面跳转
转载请注明出处:王亟亟的大牛之路 最近事情有点多,没有长时间地连贯学习,文章也停了一个多礼拜,愧疚,有时间还是继续学习,继续写! 还是先安利:https://github.com/ddwhan0123 ...
- UVA 1213 Sum of Different Primes(经典dp)
题意:选择k(k<15)个唯一质数,求出和为n(n<1121)的可能数 题解:预处理dp,dp[k][n]表示使用k个素数拼成n的总方案数 就是三重枚举,枚举k,枚举n,枚举小于n的素数 ...
- SSH 登录时出现如下错误:Host key verification failed
注意:本文相关 Linux 配置及说明已在 CentOS 6.5 64 位操作系统中进行过测试.其它类型及版本操作系统配置可能有所差异,具体情况请参阅相应操作系统官方文档. 问题描述 使用 SS ...
- docker-machine windows
windows 官方使用 https://docs.docker.com/machine/drivers/hyper-v/ 坑点是 docker-machine create -d hyperv m ...
- sa learning
后缀数组之前一直在给队友搞,但是这个类太大了,预感到青岛八成会有,于是自己也学习一下,记录一下做题的历程 所用的模板暂时来自于队友的倍增nlogn da算法 int t1[maxn] , t2[max ...