在我们平时使用应用程序时会发现一个问题,我使用应用程序时可能会接电话,或者去切出去看微信等,等在进入应用程序时,程序已经被系统杀掉。如果要继续使用应用程序需要重新登录。这样频繁反复登录会使用户极度烦躁。怎样才能保持登录态持久化就成了我们开发人员必须解决的问题。我们的目标就是想微信那样,登录一次后就算程序被系统杀掉,打开微信后也是登录的状态。
那具体要怎么做呢
首先我们要看如果跳过登录直接与服务器通信,服务器之所以知道发来请求的是我而不是别人,是以为我们在与服务器通讯的时候发送了 sessionID,而sessionID又存在了CookieStore的Cookies中。而以XUtils为例发送请求是对Cookies的操作又只有
HttpUtils http = new HttpUtils();
http.configCookieStore(CookieStore);
那如何保存CookieStore就是我们要解决的问题,解决这个问题就可以在程序被系统杀掉后吧保存的CookieStore赋给发送请求就可以达到跳过登录直接和服务器通讯的目的了。
那如何保存CookieStore呢
我们分为使用Xutils框架和没有使用Xutils框架分别讲。
1.使用了XUtils框架
在XUtils框架代码中com.lidroid.xutils.util下有个PreferencesCookieStore.java
在XUtils发送请求成功的回调中加入:
public void onSuccess(ResponseInfo<String> responseInfo) {
DefaultHttpClient dh = (DefaultHttpClient) http.getHttpClient();
CookieStore cs = dh.getCookieStore();
List<Cookie> cookies = cs.getCookies();
PreferencesCookieStore preferencesCookieStore = new PreferencesCookieStore(context);
String aa = null;
for (int i = 0; i < cookies.size(); i++) {
if ("JSESSIONID".equals(cookies.get(i).getName())) {
aa = cookies.get(i).getValue();
LoginCache.getInstance().setCookieStore(dh.getCookieStore());把CookieStore存入缓存
//把CookieStore以Cookie形式存入PreferencesCookieStore
for (Cookie cookie : cookies) {
preferencesCookieStore.addCookie(cookie);
}
break;
}
}
}
这样就成功存入preferences中了
在在程序启动的入口吧CookieStore取出并赋给缓存
PreferencesCookieStore cookieStore = new PreferencesCookieStore(context);
在给服务器发送请求时做个判断,并在请求中加上CookieStore就达到了登录态持久化,就可以直接通讯了
final HttpUtils http = new HttpUtils();
http.configCookieStore(//缓存中刚刚从PreferencesCookieStore中取出的CookieStore);
2.没有使用XUtils框架
操作步骤与上面一样只不过需要自定义PreferencesCookieStore类,上代码:
public class PreferencesCookieStore implements CookieStore {
private static final String COOKIE_PREFS = "CookiePrefsFile";
private static final String COOKIE_NAME_STORE = "names";
private static final String COOKIE_NAME_PREFIX = "cookie_";
private final ConcurrentHashMap<String, Cookie> cookies;
private final SharedPreferences cookiePrefs;
/**
* Construct a persistent cookie store.
*/
public PreferencesCookieStore(Context context) {
cookiePrefs = context.getSharedPreferences(COOKIE_PREFS,
Context.MODE_PRIVATE);
cookies = new ConcurrentHashMap<String, Cookie>();
// Load any previously stored cookies into the store
String storedCookieNames = cookiePrefs.getString(COOKIE_NAME_STORE,
null);
if (storedCookieNames != null) {
String[] cookieNames = TextUtils.split(storedCookieNames, ",");
for (String name : cookieNames) {
String encodedCookie = cookiePrefs.getString(COOKIE_NAME_PREFIX
+ name, null);
if (encodedCookie != null) {
Cookie decodedCookie = decodeCookie(encodedCookie);
if (decodedCookie != null) {
cookies.put(name, decodedCookie);
}
}
}
// Clear out expired cookies
clearExpired(new Date());
}
}
@Override
public void addCookie(Cookie cookie) {
String name = cookie.getName();
// Save cookie into local store, or remove if expired
if (!cookie.isExpired(new Date())) {
cookies.put(name, cookie);
} else {
cookies.remove(name);
}
// Save cookie into persistent store
SharedPreferences.Editor editor = cookiePrefs.edit();
editor.putString(COOKIE_NAME_STORE,
TextUtils.join(",", cookies.keySet()));
editor.putString(COOKIE_NAME_PREFIX + name,
encodeCookie(new SerializableCookie(cookie)));
editor.commit();
}
@Override
public void clear() {
// Clear cookies from persistent store
SharedPreferences.Editor editor = cookiePrefs.edit();
for (String name : cookies.keySet()) {
editor.remove(COOKIE_NAME_PREFIX + name);
}
editor.remove(COOKIE_NAME_STORE);
editor.commit();
// Clear cookies from local store
cookies.clear();
}
@Override
public boolean clearExpired(Date date) {
boolean clearedAny = false;
SharedPreferences.Editor editor = cookiePrefs.edit();
for (ConcurrentHashMap.Entry<String, Cookie> entry : cookies.entrySet()) {
String name = entry.getKey();
Cookie cookie = entry.getValue();
if (cookie.getExpiryDate() == null || cookie.isExpired(date)) {
// Remove the cookie by name
cookies.remove(name);
// Clear cookies from persistent store
editor.remove(COOKIE_NAME_PREFIX + name);
// We've cleared at least one
clearedAny = true;
}
}
// Update names in persistent store
if (clearedAny) {
editor.putString(COOKIE_NAME_STORE,
TextUtils.join(",", cookies.keySet()));
}
editor.commit();
return clearedAny;
}
@Override
public List<Cookie> getCookies() {
return new ArrayList<Cookie>(cookies.values());
}
public Cookie getCookie(String name) {
return cookies.get(name);
}
protected String encodeCookie(SerializableCookie cookie) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ObjectOutputStream outputStream = new ObjectOutputStream(os);
outputStream.writeObject(cookie);
} catch (Throwable e) {
return null;
}
return byteArrayToHexString(os.toByteArray());
}
protected Cookie decodeCookie(String cookieStr) {
byte[] bytes = hexStringToByteArray(cookieStr);
ByteArrayInputStream is = new ByteArrayInputStream(bytes);
Cookie cookie = null;
try {
ObjectInputStream ois = new ObjectInputStream(is);
cookie = ((SerializableCookie) ois.readObject()).getCookie();
} catch (Throwable e) {
LogUtils.e(e.getMessage(), e);
}
return cookie;
}
// Using some super basic byte array <-> hex conversions so we don't have
// to rely on any large Base64 libraries. Can be overridden if you like!
protected String byteArrayToHexString(byte[] b) {
StringBuffer sb = new StringBuffer(b.length * 2);
for (byte element : b) {
int v = element & 0xff;
if (v < 16) {
sb.append('0');
}
sb.append(Integer.toHexString(v));
}
return sb.toString().toUpperCase();
}
protected byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character
.digit(s.charAt(i + 1), 16));
}
return data;
}
public class SerializableCookie implements Serializable {
private static final long serialVersionUID = 6374381828722046732L;
private transient final Cookie cookie;
private transient BasicClientCookie clientCookie;
public SerializableCookie(Cookie cookie) {
this.cookie = cookie;
}
public Cookie getCookie() {
Cookie bestCookie = cookie;
if (clientCookie != null) {
bestCookie = clientCookie;
}
return bestCookie;
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.writeObject(cookie.getName());
out.writeObject(cookie.getValue());
out.writeObject(cookie.getComment());
out.writeObject(cookie.getDomain());
out.writeObject(cookie.getExpiryDate());
out.writeObject(cookie.getPath());
out.writeInt(cookie.getVersion());
out.writeBoolean(cookie.isSecure());
}
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
String name = (String) in.readObject();
String value = (String) in.readObject();
clientCookie = new BasicClientCookie(name, value);
clientCookie.setComment((String) in.readObject());
clientCookie.setDomain((String) in.readObject());
clientCookie.setExpiryDate((Date) in.readObject());
clientCookie.setPath((String) in.readObject());
clientCookie.setVersion(in.readInt());
clientCookie.setSecure(in.readBoolean());
}
}
}
以上就是如何使登录态持久化,希望对大家有用。