在SharedPreference中添加会话信息并检索它

时间:2018-08-19 07:17:01

标签: java android session sharedpreferences

我想将会话密钥和其他信息存储在sharedpreference中,并在调用另一个api时将其检索。我指的是这个答案-https://stackoverflow.com/a/16743595/10243953。我制作了一个单独的类MyApp,并调用了其用于存储和检索信息的方法。这是我的第一个带有会话的项目,所以我不太了解,但是我尝试了这段代码。

登录功能

public void LoginAPI(){
    progressDialog.show();
    StringRequest stringRequest = new StringRequest(Request.Method.POST, LOGIN_URL, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {

      // My Operations with response

    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            progressDialog.dismiss();
            Snackbar.make(v,"LOGIN FAILED",Snackbar.LENGTH_SHORT).show();
        }
    }){
        @Override
        protected Map<String, String> getParams() {
            Map<String, String> params = new HashMap<>();
            // the POST parameters:
            params.put("identity", username);
            params.put("pass",password);
            return params;
        }


      //Storing Session Data
        @Override
        protected Response<String> parseNetworkResponse(NetworkResponse response) {
            MyApp.get().checkSessionCookie(response.headers);
            return super.parseNetworkResponse(response);
        }

    };
    RequestQueue queue = Volley.newRequestQueue(this);
    queue.add(stringRequest);
}

获取数据以添加会话数据

public void GetStudentData(){
    progressBar.setVisibility(View.VISIBLE);
    String parent_id = SharedPreferenceManager.getmInstance(getContext()).getID();
    StringRequest stringRequest = new StringRequest(Request.Method.GET, GET_STUDENT_URL+parent_id, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            progressBar.setVisibility(View.GONE);
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

        }
    }){
        @Override
        protected Response<String> parseNetworkResponse(NetworkResponse response) {

            return super.parseNetworkResponse(response);
        }

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String,String> headers = super.getHeaders();
            if (headers == null || headers.equals(Collections.<String, String>emptyMap())){
                headers = new HashMap<String, String>();
            }
            MyApp.get().addSessionCookie(headers);
            return headers;
        }
    };
    RequestQueue queue = Volley.newRequestQueue(getContext());
    queue.add(stringRequest);
}

MyApp

public class MyApp extends Application {
private static final String SET_COOKIE_KEY = "Set-Cookie";
private static final String COOKIE_KEY = "Cookie";
private static final String SESSION_COOKIE = "sessionid";

private static MyApp _instance;
private RequestQueue _requestQueue;
private SharedPreferences _preferences;

public static MyApp get() {
    return _instance;
}

@Override
public void onCreate() {
    super.onCreate();
    _instance = this;
    _preferences = PreferenceManager.getDefaultSharedPreferences(this);
    _requestQueue = Volley.newRequestQueue(this);
}

public RequestQueue getRequestQueue() {
    return _requestQueue;
}


/**
 * Checks the response headers for session cookie and saves it
 * if it finds it.
 * @param headers Response Headers.
 */
public final void checkSessionCookie(Map<String, String> headers) {
    if (headers.containsKey(SET_COOKIE_KEY)
            && headers.get(SET_COOKIE_KEY).startsWith(SESSION_COOKIE)) {
        String cookie = headers.get(SET_COOKIE_KEY);
        if (cookie.length() > 0) {
            String[] splitCookie = cookie.split(";");
            String[] splitSessionId = splitCookie[0].split("=");
            cookie = splitSessionId[1];
            SharedPreferences.Editor prefEditor = _preferences.edit();
            prefEditor.putString(SESSION_COOKIE, cookie);
            prefEditor.commit();
        }
    }
}

/**
 * Adds session cookie to headers if exists.
 * @param headers
 */
public final void addSessionCookie(Map<String, String> headers) {
    String sessionId = _preferences.getString(SESSION_COOKIE, "");
    if (sessionId.length() > 0) {
        StringBuilder builder = new StringBuilder();
        builder.append(SESSION_COOKIE);
        builder.append("=");
        builder.append(sessionId);
        if (headers.containsKey(COOKIE_KEY)) {
            builder.append("; ");
            builder.append(headers.get(COOKIE_KEY));
        }
        headers.put(COOKIE_KEY, builder.toString());
    }
}
}

证据

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.acg.digimkeyparent">
<!-- To auto-complete the email text field in the login form with the user's emails -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:usesCleartextTraffic="true">
    <activity
        android:name=".Slide"
        android:theme="@style/Theme.AppCompat.NoActionBar" />
    <activity
        android:name=".Login"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
    <activity
        android:name=".ForgotPassword"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
    <activity android:name=".ResetPassword" />
    <activity android:name=".EditNumber" />
    <activity android:name=".OTP" />
    <activity android:name=".ProfileChild" />
    <activity
        android:name=".SplashScreen"
        android:theme="@style/Theme.AppCompat.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service
        android:name=".GSMRegistrationIntentService"
        android:exported="false">
        <intent-filter>
            <action android:name="com.google.android.gms.iid.InstanceID" />
        </intent-filter>
    </service>

    <activity
        android:name=".MainActivity"
        android:label="@string/title_activity_main" />
    <activity android:name=".ChangePassword" />
    <activity android:name=".ChangeMobile" />
    <activity android:name=".StudentDashboard" />
</application>
</manifest>

错误-登录功能

E/Volley: [462] NetworkDispatcher.processRequest: Unhandled exception java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.acg.digimkeyparent.MyApp.checkSessionCookie(java.util.Map)' on a null object reference
      java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.acg.digimkeyparent.MyApp.checkSessionCookie(java.util.Map)' on a null object reference
          at com.example.acg.digimkeyparent.Login$5.parseNetworkResponse(Login.java:186)
          at com.android.volley.NetworkDispatcher.processRequest(NetworkDispatcher.java:132)
          at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:87)

2 个答案:

答案 0 :(得分:0)

将此行android:name=".MyApp"添加到AndroidManifest.xml文件中的应用程序标记中

<application
    android:name=".MyApp"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:usesCleartextTraffic="true">

尝试一下!

答案 1 :(得分:0)

我将删除该MyApp.get(),它返回NULL并进行静态调用,例如:

public static boolean checkSessionCookie(Map<String, String> headers) {
    if (headers.containsKey(SET_COOKIE_KEY) && headers.get(SET_COOKIE_KEY).startsWith(SESSION_COOKIE)) {
        String cookie = headers.get(SET_COOKIE_KEY);
        if (cookie.length() > 0) {

            String[] splitCookie = cookie.split(";");
            String[] splitSessionId = splitCookie[0].split("=");
            cookie = splitSessionId[1];

            SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
            SharedPreferences.Editor prefEditor = preferences.edit();
            prefEditor.putString(SESSION_COOKIE, cookie);
            prefEditor.commit();

            return true;
        }
    }
    return false;
}

同样可用boolean hasCookie = MyApp.checkSessionCookie(response.headers);

...在MyApp中引用Mainfest.xml时,它还应返回实例,具有static Context字段的对象很容易Context leaks;最好尽可能避免。您只需要从该Preferences方法中获取static的句柄; getApplicationContext()最有可能满足要求。