使用 HttpClient 时跨 Activity 使用 Cookie

发布于 2024-11-03 10:50:47 字数 6191 浏览 1 评论 0原文

我正在尝试一个简单的应用程序来读取网站的 HTML,并将其转换为在 Android 中创建一个易于阅读的 UI(这是学习 android 的练习,而不是制作一个可用的应用程序)。我遇到的问题是在 Activity 之间保留用户会话,然后在调用后在 HttpClient 中使用该会话。

我想“正确”地做到这一点,推荐的方法似乎是使用 CookieManager 。然而我遇到了问题 - 我似乎找不到从 CookieManager 获取 Cookie 并在以后的 实例化中使用它的“正确”方法>HttpClient 在单独的活动中。

使用 CookieManager 时,我可以保存 Cookie,然后 Cookie 就在其他活动的范围内(参见代码片段 2)。我还没有找到稍后在请求页面时如何使用它(参见代码片段3)。

说得够多了,这是一些代码。首先是我的登录操作和 Cookie 存储:

private OnClickListener loginActionListener = new OnClickListener() 
{
    public void onClick(View v) 
    {
        EditText usernameTextView = (EditText) findViewById(R.id.Username);
        EditText passwordTextView = (EditText) findViewById(R.id.Password);
        String username = usernameTextView.getText().toString();
        String password = passwordTextView.getText().toString();

        try {
            HttpPost postMethod = new HttpPost(URI);                
            HttpParams params   = new BasicHttpParams();

            params.setParameter("mode", "login");
            params.setParameter("autologin", true);
            params.setParameter("username", username);
            params.setParameter("password", password);
            postMethod.setParams(params);

            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpResponse response        = httpClient.execute(postMethod);
            List<Cookie> cookies = httpClient.getCookieStore().getCookies();

            if(cookies != null)
            {
                for(Cookie cookie : cookies)
                {
                    String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain();                        
                    CookieManager.getInstance().setCookie(cookie.getDomain(), cookieString);  
                }
            }
            CookieSyncManager.getInstance().sync();

            Intent intent = new Intent(v.getContext(), IndexAction.class);
            startActivity(intent);
    } catch (Exception e) {...}
}

下面是决定是让用户登录还是转到索引的启动活动。您可以从这段代码中看到 cookie 在范围内并且可以读取:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    CookieSyncManager.createInstance(this);

    if(CookieManager.getInstance().getCookie(URI) == null)
    {
        Intent intent = new Intent(this, LoginAction.class);
        startActivity(intent);
    }
    else
    {
        Intent intent = new Intent(this, IndexAction.class);
        startActivity(intent);
    }
}

但是从我的代码读取索引页面,我希望您能提出我所缺少的内容:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    CookieSyncManager.createInstance(this);

    try
    {
            HttpGet getMethod = new HttpGet(URI_INDEX);  

            HttpParams params   = new BasicHttpParams();                        
            HttpConnectionParams.setConnectionTimeout(params, 30000);
            HttpConnectionParams.setSoTimeout(params, 30000);

            // This code results in a ClassCastException, I'm assuming i've found a red herring with this solution.
            // HttpContext localContext = new BasicHttpContext();    
            // localContext.setAttribute(ClientContext.COOKIE_STORE, CookieManager.getInstance().getCookie(URI));

            DefaultHttpClient httpClient = new DefaultHttpClient(params);
            HttpResponse response        = httpClient.execute(getMethod);

            if(response.getStatusLine().getStatusCode() > 299 && response.getStatusLine().getStatusCode() < 400)
            {
                // Not logged in doesn't give a redirect response. Very annoying.
            }

            final char[] buffer = new char[0x10000];
            StringBuilder out = new StringBuilder();
            Reader in = new InputStreamReader(response.getEntity().getContent(), "UTF-8");
            int read = 0;
            while (read>=0)
            {
              read = in.read(buffer, 0, buffer.length);
              if (read>0) {
                out.append(buffer, 0, read);
              }
            }

            String returnString = out.toString();
    } catch (ClientProtocolException e) {...}
}

HttpClient on < code>execute(getMethod) 没有使用 Cookie(在调试中仔细检查)来拉回页面。如果有人能填补我的知识空白,那就太好了。

提前致谢。

编辑

当注释代码添加回来时(将 httpClient.execute(getMethod) 方法更改为 httpClient.execute(getMethod, localContext))生成此跟踪跟踪 - 假设是因为我使用 Cookie String 而不是填充属性 ClientContext.COOKIE_STORE CookieStore:

*org.apache.http.client.protocol.RequestAddCookies.process(RequestAddCookies.java:88), org.apache.http.protocol.BasicHttpProcessor.process(BasicHttpProcessor.java:290), org.apache.http.protocol.HttpRequestExecutor.preProcess(HttpRequestExecutor.java:160), org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:401)
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555), org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487), 
com.testapp.site.name.IndexAction.onCreate(IndexAction.java:47), 
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047), 
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611), 
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663), 
android.app.ActivityThread.access$1500(ActivityThread.java:117), 
android.app.ActivityThread$H.handleMessage(ActivityThread.java:931), 
android.os.Handler.dispatchMessage(Handler.java:99), 
android.os.Looper.loop(Looper.java:123), 
android.app.ActivityThread.main(ActivityThread.java:3683), 
java.lang.reflect.Method.invokeNative(Native Method), 
java.lang.reflect.Method.invoke(Method.java:507), 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839), 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597), 
dalvik.system.NativeStart.main(Native Method)*

I'm trying a simple app to read in the HTML of a website, and tranform it to create an easily readable UI in Android (This is an exersize in learning android, not to make a useable app). The problem I'm having is persisting a users session across Activities and then using the session in a HttpClient once recalled.

I would like to do this "Correctly", the recommended approach seem to be to use CookieManager. I've had problems with this however - I cannot seem to find the "Correct" way to take a Cookie from the CookieManager and use it in a later instantiation of HttpClient in a seperate Activities.

When using a CookieManager I can save the Cookie and the Cookie is then in scope in other Activities (See code snippet 2). I haven't found how to use this later (See code snippet 3) when requesting a page.

Enough talking, here is some code. First my login action and Cookie storage:

private OnClickListener loginActionListener = new OnClickListener() 
{
    public void onClick(View v) 
    {
        EditText usernameTextView = (EditText) findViewById(R.id.Username);
        EditText passwordTextView = (EditText) findViewById(R.id.Password);
        String username = usernameTextView.getText().toString();
        String password = passwordTextView.getText().toString();

        try {
            HttpPost postMethod = new HttpPost(URI);                
            HttpParams params   = new BasicHttpParams();

            params.setParameter("mode", "login");
            params.setParameter("autologin", true);
            params.setParameter("username", username);
            params.setParameter("password", password);
            postMethod.setParams(params);

            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpResponse response        = httpClient.execute(postMethod);
            List<Cookie> cookies = httpClient.getCookieStore().getCookies();

            if(cookies != null)
            {
                for(Cookie cookie : cookies)
                {
                    String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain();                        
                    CookieManager.getInstance().setCookie(cookie.getDomain(), cookieString);  
                }
            }
            CookieSyncManager.getInstance().sync();

            Intent intent = new Intent(v.getContext(), IndexAction.class);
            startActivity(intent);
    } catch (Exception e) {...}
}

The startup Activity which decides wether to make the user login or go to the index is below. You can see from this code that the cookie is in scope and can be read:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    CookieSyncManager.createInstance(this);

    if(CookieManager.getInstance().getCookie(URI) == null)
    {
        Intent intent = new Intent(this, LoginAction.class);
        startActivity(intent);
    }
    else
    {
        Intent intent = new Intent(this, IndexAction.class);
        startActivity(intent);
    }
}

But from my code to read the Index page I'm hoping you can suggest what i'm missing:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    CookieSyncManager.createInstance(this);

    try
    {
            HttpGet getMethod = new HttpGet(URI_INDEX);  

            HttpParams params   = new BasicHttpParams();                        
            HttpConnectionParams.setConnectionTimeout(params, 30000);
            HttpConnectionParams.setSoTimeout(params, 30000);

            // This code results in a ClassCastException, I'm assuming i've found a red herring with this solution.
            // HttpContext localContext = new BasicHttpContext();    
            // localContext.setAttribute(ClientContext.COOKIE_STORE, CookieManager.getInstance().getCookie(URI));

            DefaultHttpClient httpClient = new DefaultHttpClient(params);
            HttpResponse response        = httpClient.execute(getMethod);

            if(response.getStatusLine().getStatusCode() > 299 && response.getStatusLine().getStatusCode() < 400)
            {
                // Not logged in doesn't give a redirect response. Very annoying.
            }

            final char[] buffer = new char[0x10000];
            StringBuilder out = new StringBuilder();
            Reader in = new InputStreamReader(response.getEntity().getContent(), "UTF-8");
            int read = 0;
            while (read>=0)
            {
              read = in.read(buffer, 0, buffer.length);
              if (read>0) {
                out.append(buffer, 0, read);
              }
            }

            String returnString = out.toString();
    } catch (ClientProtocolException e) {...}
}

The HttpClient on execute(getMethod) isn't using the Cookie (double checked this in debug) to pull back the page. It would be great if someone could fill this hole in my knowledge.

Thanks in advance.

EDIT

When commented code is added back in (with the httpClient.execute(getMethod) method change to httpClient.execute(getMethod, localContext)) this strack trace is produced - Assumedly because i'm filling the attribute ClientContext.COOKIE_STORE with a Cookie String rather than a CookieStore:

*org.apache.http.client.protocol.RequestAddCookies.process(RequestAddCookies.java:88), org.apache.http.protocol.BasicHttpProcessor.process(BasicHttpProcessor.java:290), org.apache.http.protocol.HttpRequestExecutor.preProcess(HttpRequestExecutor.java:160), org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:401)
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555), org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487), 
com.testapp.site.name.IndexAction.onCreate(IndexAction.java:47), 
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047), 
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611), 
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663), 
android.app.ActivityThread.access$1500(ActivityThread.java:117), 
android.app.ActivityThread$H.handleMessage(ActivityThread.java:931), 
android.os.Handler.dispatchMessage(Handler.java:99), 
android.os.Looper.loop(Looper.java:123), 
android.app.ActivityThread.main(ActivityThread.java:3683), 
java.lang.reflect.Method.invokeNative(Native Method), 
java.lang.reflect.Method.invoke(Method.java:507), 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839), 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597), 
dalvik.system.NativeStart.main(Native Method)*

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

北城半夏 2024-11-10 10:50:48

我也有同样的问题。由于我使用的是 Volley 而不是直接使用 HTTPClient,HTTPClient 的单例似乎不是正确的解决方案。但使用同样的想法,我只是将 CookieManager 保存在我的应用程序单例中。
因此,如果 app 是我的应用程序单例,那么在每个活动的 onCreate() 中,我添加以下内容:

    if (app.cookieManager == null) {
        app.cookieManager = new CookieManager(null, CookiePolicy.ACCEPT_ALL);
    }
    CookieHandler.setDefault(app.cookieManager);

为了使这一点更好,我的所有活动都是 MyAppActivity 的子类,因此我所要做的就是将其放在 MyAppActivity 的 onCreate() 中,然后我的所有活动都继承了这个功能。现在我的所有活动都使用相同的 cookie 管理器,并且我的 Web 服务会话由所有活动共享。简单而且效果很好。

I had the same problem. Since I am using Volley and not HTTPClient directly the Singleton for HTTPClient didn't seem like the correct solution. But using that same idea I simply saved the CookieManager in my application singleton.
So if app is my application singleton then in the onCreate() of each activity I add this:

    if (app.cookieManager == null) {
        app.cookieManager = new CookieManager(null, CookiePolicy.ACCEPT_ALL);
    }
    CookieHandler.setDefault(app.cookieManager);

To make this even better, all of my activities are subclasses of MyAppActivity so all I have to do is put it in the onCreate for MyAppActivity and then all of my activities inherit this functionality. Now all my activities are using the same cookie manager and my web service session is shared by all the activities. Simple and it works great.

慕巷 2024-11-10 10:50:48

我想最好的事情之一是将单例模式应用于您的 HTTPClient,这样您就只有一个实例!

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;

public class myHttpClient {
    private static HttpClient mClient;
    private myHttpClient() {};
    public static HttpClient getInstance() {
        if(mClient==null)
            mClient = new DefaultHttpClient();
        return mClient;
    }
}

I suppose one of best thing is apply Singleton Pattern to your HTTPClient so you just have only one instance!

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;

public class myHttpClient {
    private static HttpClient mClient;
    private myHttpClient() {};
    public static HttpClient getInstance() {
        if(mClient==null)
            mClient = new DefaultHttpClient();
        return mClient;
    }
}
裸钻 2024-11-10 10:50:48

cookie 存储的一个好的解决方案是遵循 ThreadLocal 模式,以避免随机存储 cookie。

这将有助于保持唯一的 CookieStore。有关此模式的更多说明,您可以点击此有用的链接。

http://veerasundar. com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/

干杯

A good solution for the cookie storage would be to follow the ThreadLocal pattern in order to avoid storing cookies randomly.

This will help keeping a one and only CookieStore. For more explanation of this pattern, you can follow this useful link.

http://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/

Cheers

与之呼应 2024-11-10 10:50:47

CookieManager 由 Java 的内部 HTTP 客户端使用。它与 Apache HttpClient 无关。

在您的代码中,您总是为每个请求创建一个新的 HttpClient 实例,因此创建一个新的 CookieStore 实例,显然,该实例会立即与存储在其中的所有 cookie 一起被垃圾收集。 HttpClient 实例超出范围。

您应该

(1) 对于所有逻辑相关的 HTTP 请求重复使用 HttpClient 的相同实例,并在所有逻辑相关的线程之间共享它(这是推荐的使用方式) Apache HttpClient)

(2) 或者至少在逻辑相关的线程之间共享 CookieStore 的相同实例

(3) 或者,如果您坚持使用 CookieManager 来存储您的所有 cookie,创建由 CookieManager 支持的自定义 CookieStore 实现

CookieManager is used by the Java's internal HTTP client. It has nothing to do with Apache HttpClient.

In your code you always create for each request a new instance of HttpClient and therefore a new CookieStore instance, which obviously gets garbage collected along with all cookies stored in as soon as that HttpClient instance goes out of scope.

You should either

(1) Re-use the same instance of HttpClient for all logically related HTTP requests and share it between all logically related threads (which is the recommended way of using Apache HttpClient)

(2) or, at the very least, share the same instance of CookieStore between logically related threads

(3) or, if you insist on using CookieManager to store all your cookies, create a custom CookieStore implementation backed by CookieManager

皓月长歌 2024-11-10 10:50:47

(正如所承诺的解决方案。我仍然不喜欢它,并且觉得我错过了执行此操作的“正确”方法,但是它有效。)

您可以使用 CookieManager使用以下代码注册您的 cookie(从而使这些 cookie 在应用程序之间可用):

将 cookie 保存到 CookieManager 中:

List<Cookie> cookies = httpClient.getCookieStore().getCookies();

if(cookies != null)
{
    for(Cookie cookie : cookies)
    {
        String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain();                        
        CookieManager.getInstance().setCookie(cookie.getDomain(), cookieString);  
    }
}
CookieSyncManager.getInstance().sync();

检查指定域上的 cookie:
if(CookieManager.getInstance().getCookie(URI_FOR_DOMAIN)

重建 HttpClient 的值:

DefaultHttpClient httpClient = new DefaultHttpClient(params);
String[] keyValueSets = CookieManager.getInstance().getCookie(URI_FOR_DOMAIN).split(";");
for(String cookie : keyValueSets)
{
    String[] keyValue = cookie.split("=");
    String key = keyValue[0];
    String value = "";
    if(keyValue.length>1) value = keyValue[1];
    httpClient.getCookieStore().addCookie(new BasicClientCookie(key, value));
}

(As promised a solution to this. I still don't like it and feel like I'm missing out on the "Correct" way of doing this but, it works.)

You can use the CookieManager to register your cookies (and therefore make these cookies available between apps) with the following code:

Saving cookies into the CookieManager:

List<Cookie> cookies = httpClient.getCookieStore().getCookies();

if(cookies != null)
{
    for(Cookie cookie : cookies)
    {
        String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain();                        
        CookieManager.getInstance().setCookie(cookie.getDomain(), cookieString);  
    }
}
CookieSyncManager.getInstance().sync();

Checking for cookies on specified domain:
if(CookieManager.getInstance().getCookie(URI_FOR_DOMAIN)

To reconstruct values for HttpClient:

DefaultHttpClient httpClient = new DefaultHttpClient(params);
String[] keyValueSets = CookieManager.getInstance().getCookie(URI_FOR_DOMAIN).split(";");
for(String cookie : keyValueSets)
{
    String[] keyValue = cookie.split("=");
    String key = keyValue[0];
    String value = "";
    if(keyValue.length>1) value = keyValue[1];
    httpClient.getCookieStore().addCookie(new BasicClientCookie(key, value));
}
晨敛清荷 2024-11-10 10:50:47

在我的应用程序服务器中想要使用具有相同 cookie 的相同会话...
经过几个小时的“谷歌搜索”和痛苦的头痛之后,我只是将 cookie 保存到 SharedPreference 中,或者只是放入一些对象并再次使用相同的 cookie 设置 DefaultHttpClient ... onDestroy 只是删除 SharedPreferences ... 这就是全部:

  1. 首先将 SerializedCookie 类复制到您的包中:
    SerializedCookie

看下面的例子:

public class NodeServerTask extends AsyncTask<Void, Void, String> {
private DefaultHttpClient client;


protected String doInBackground(Void... params) {
  HttpPost httpPost = new HttpPost(url);
    List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
    urlParameters.add(nameValuePair);
    try {
        httpPost.setEntity(new UrlEncodedFormEntity(urlParameters));
        List<Cookie> cookies = loadSharedPreferencesCookie();
        if (cookies!=null){
            CookieStore cookieStore = new BasicCookieStore();
            for (int i=0; i<cookies.size(); i++)
                cookieStore.addCookie(cookies.get(i));
            client.setCookieStore(cookieStore);
        }
        HttpResponse response = client.execute(httpPost);
        cookies = client.getCookieStore().getCookies();

        saveSharedPreferencesCookies(cookies);

// 两种方法保存并加载cookie...

 private void saveSharedPreferencesCookies(List<Cookie> cookies) {
    SerializableCookie[] serializableCookies = new SerializableCookie[cookies.size()];
    for (int i=0;i<cookies.size();i++){
        SerializableCookie serializableCookie = new SerializableCookie(cookies.get(i));
        serializableCookies[i] = serializableCookie;
    }
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    SharedPreferences.Editor editor = preferences.edit();
    ObjectOutputStream objectOutput;
    ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
    try {
        objectOutput = new ObjectOutputStream(arrayOutputStream);


        objectOutput.writeObject(serializableCookies);
        byte[] data = arrayOutputStream.toByteArray();
        objectOutput.close();
        arrayOutputStream.close();

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        Base64OutputStream b64 = new Base64OutputStream(out, Base64.DEFAULT);
        b64.write(data);
        b64.close();
        out.close();

        editor.putString("cookies", new String(out.toByteArray()));
        editor.apply();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private List<Cookie> loadSharedPreferencesCookie() {
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    byte[] bytes = preferences.getString("cookies", "{}").getBytes();
    if (bytes.length == 0 || bytes.length==2)
        return null;
    ByteArrayInputStream byteArray = new ByteArrayInputStream(bytes);
    Base64InputStream base64InputStream = new Base64InputStream(byteArray, Base64.DEFAULT);
    ObjectInputStream in;
    List<Cookie> cookies = new ArrayList<Cookie>();
    SerializableCookie[] serializableCookies;
    try {
        in = new ObjectInputStream(base64InputStream);
        serializableCookies = (SerializableCookie[]) in.readObject();
        for (int i=0;i<serializableCookies.length; i++){
            Cookie cookie = serializableCookies[i].getCookie();
            cookies.add(cookie);
        }
        return cookies;
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return null;
}

Google Luck

In my application server wants to use same session with same cookies...
After few hours of "googling" and painful headache I just saved cookies to SharedPreference or just put in some object and set DefaultHttpClient with same cookies again ... onDestroy just remove SharedPreferences ... that's all:

  1. First copy SerializableCookie class to your package:
    SerializableCookie

Look the following example:

public class NodeServerTask extends AsyncTask<Void, Void, String> {
private DefaultHttpClient client;


protected String doInBackground(Void... params) {
  HttpPost httpPost = new HttpPost(url);
    List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
    urlParameters.add(nameValuePair);
    try {
        httpPost.setEntity(new UrlEncodedFormEntity(urlParameters));
        List<Cookie> cookies = loadSharedPreferencesCookie();
        if (cookies!=null){
            CookieStore cookieStore = new BasicCookieStore();
            for (int i=0; i<cookies.size(); i++)
                cookieStore.addCookie(cookies.get(i));
            client.setCookieStore(cookieStore);
        }
        HttpResponse response = client.execute(httpPost);
        cookies = client.getCookieStore().getCookies();

        saveSharedPreferencesCookies(cookies);

// two methods to save and load cookies ...

 private void saveSharedPreferencesCookies(List<Cookie> cookies) {
    SerializableCookie[] serializableCookies = new SerializableCookie[cookies.size()];
    for (int i=0;i<cookies.size();i++){
        SerializableCookie serializableCookie = new SerializableCookie(cookies.get(i));
        serializableCookies[i] = serializableCookie;
    }
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    SharedPreferences.Editor editor = preferences.edit();
    ObjectOutputStream objectOutput;
    ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
    try {
        objectOutput = new ObjectOutputStream(arrayOutputStream);


        objectOutput.writeObject(serializableCookies);
        byte[] data = arrayOutputStream.toByteArray();
        objectOutput.close();
        arrayOutputStream.close();

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        Base64OutputStream b64 = new Base64OutputStream(out, Base64.DEFAULT);
        b64.write(data);
        b64.close();
        out.close();

        editor.putString("cookies", new String(out.toByteArray()));
        editor.apply();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private List<Cookie> loadSharedPreferencesCookie() {
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
    byte[] bytes = preferences.getString("cookies", "{}").getBytes();
    if (bytes.length == 0 || bytes.length==2)
        return null;
    ByteArrayInputStream byteArray = new ByteArrayInputStream(bytes);
    Base64InputStream base64InputStream = new Base64InputStream(byteArray, Base64.DEFAULT);
    ObjectInputStream in;
    List<Cookie> cookies = new ArrayList<Cookie>();
    SerializableCookie[] serializableCookies;
    try {
        in = new ObjectInputStream(base64InputStream);
        serializableCookies = (SerializableCookie[]) in.readObject();
        for (int i=0;i<serializableCookies.length; i++){
            Cookie cookie = serializableCookies[i].getCookie();
            cookies.add(cookie);
        }
        return cookies;
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    return null;
}

Google Luck

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文