XUtils框架之登录态持久化机制(session保留机制)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Terry_722/article/details/51097743


            在我们平时使用应用程序时会发现一个问题,我使用应用程序时可能会接电话,或者去切出去看微信等,等在进入应用程序时,程序已经被系统杀掉。如果要继续使用应用程序需要重新登录。这样频繁反复登录会使用户极度烦躁。怎样才能保持登录态持久化就成了我们开发人员必须解决的问题。我们的目标就是想微信那样,登录一次后就算程序被系统杀掉,打开微信后也是登录的状态。


        那具体要怎么做呢

        首先我们要看如果跳过登录直接与服务器通信,服务器之所以知道发来请求的是我而不是别人,是以为我们在与服务器通讯的时候发送了 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());
		}
	}
}

以上就是如何使登录态持久化,希望对大家有用。






阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页