如何处理 android 应用程序的用户会话
How to handle a user session for android app
我正在创建一个应用程序,用户可以在其中使用他们的登录详细信息登录。
一旦用户通过验证,用户数据将从网络服务器下载到名为 User 的 class 中。用户 class 保存用户信息,例如姓名、年龄、生日、用户名、电子邮件等。用户 class 每个应用程序生命周期只会实例化一次。以前,我将 User class 实例化为一个 public 静态变量,这样我就可以轻松地从每个其他 activity 和 class 访问它,但这是不好的做法,因为由于缺乏封装,我需要帮助弄清楚如何处理用户 class。
谢谢
编辑:
这是我的登录代码:
private class LoginTask extends AsyncTask<String, JSONObject, Boolean> {
private String email, password;
private ProgressBar progressBar;
public LoginTask(ProgressBar progressBar, String email, String password) {
this.progressBar = progressBar;
this.email = email;
this.password = password;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.setVisibility(View.VISIBLE);
}
private HttpURLConnection loginConnection(String email, String encPass)
{
return Connection.getConnection(Links.LOGIN_SCRIPT, "email=" + email + "&password=" + encPass);
}
private HttpURLConnection saltConnection(String email) {
return Connection.getConnection(Links.GET_SALT, "request_salt=set&request_email=" + email);
}
private HttpURLConnection existsConnection(String email) {
return Connection.getConnection(Links.USER_EXISTS + "?email=" + email);
}
@Override
protected Boolean doInBackground(String... info) {
try {
String existString = Connection.getStringFromConnection(existsConnection(email));
int existInt = Integer.parseInt(existString);
if (existInt == Connection.SUCCESS) {
String saltString = Connection.getStringFromConnection(saltConnection(email));
JSONObject saltJson = new JSONObject(saltString);
String salt = saltJson.getString("salt"); //Perfect
if (salt.length() > 0) {
String encPass = Utils.SHA256(password + salt);
JSONObject encPassObj = new JSONObject();
encPassObj.put("email", email);
encPassObj.put("encPass", encPass);
publishProgress(encPassObj);
if (encPass.length() > 0) {
String loginString = Connection.getStringFromConnection(loginConnection(email, encPass));
int logInt = Integer.parseInt(loginString);
if (logInt == Connection.SUCCESS) {
//Globals.user = new User(email, encPass);
return true;
} else {
return false;
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
@Override
protected void onProgressUpdate(JSONObject... values) {
super.onProgressUpdate(values);
try {
JSONObject object = values[0];
setEmail(object.getString("email"));
setPassword(object.getString("encPass"));
preferences.saveLoginDetails(object.getString("email"), object.getString("encPass"));
} catch (JSONException e) {
e.printStackTrace();
}
}
//UI
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
progressBar.setVisibility(View.INVISIBLE);
}
}
LoginTask 将根据成功登录 return 真值或假值,电子邮件和加密密码将用于在全局 class.
示例:
public class Global {
public static User user = new User(email, password);
}
我这里唯一的问题是用户的封装 class。我该如何改进它?
由于您的应用程序只有一个用户,因此您可以创建一个非常简单的 class,其中包含只能初始化一次的静态字段。
快速示例:
public class UserUtil {
private static String email;
private static int UID;
//etc
private static boolean initialized=false;
static public void initUserDetails(String email, int uid,//etc){
if (initialized==true)
throw new IllegalStateException("Error, User has already been initialized");
this.email=email;
this.UID=uid;
//etc
initialized=true;
}
//static public getters for private variables
}
试试这个...
将数据存储到本地数据库。同样通过本地数据库,您不需要一次又一次地下载数据。
如果您只有一个用户,那么您需要将您的 class 设置为单例 class。这样你就知道 class 只有一个实例,并且每个 activity 访问它都将使用同一个对象。
看这道题:Creating an Object accessible by all Activites in Android
所以假设我们创建了一个 Singleton class,如下所示:
public class SessionUser {
private static SessionUser instance = null;
protected SessionUser() {
// Exists only to defeat instantiation.
}
public static SessionUser getInstance() {
if(instance == null) {
instance = new SessionUser();
}
return instance;
}
private boolean isUserInSession()
{
//validation code
return isInSession;
}
}
你可以像这样在任何 class 中使用它:
//Some code
if (!SessionUser.getInstance().isUserInSession())
{
//Go to login
}
//More code
我正在创建一个应用程序,用户可以在其中使用他们的登录详细信息登录。 一旦用户通过验证,用户数据将从网络服务器下载到名为 User 的 class 中。用户 class 保存用户信息,例如姓名、年龄、生日、用户名、电子邮件等。用户 class 每个应用程序生命周期只会实例化一次。以前,我将 User class 实例化为一个 public 静态变量,这样我就可以轻松地从每个其他 activity 和 class 访问它,但这是不好的做法,因为由于缺乏封装,我需要帮助弄清楚如何处理用户 class。
谢谢
编辑: 这是我的登录代码:
private class LoginTask extends AsyncTask<String, JSONObject, Boolean> {
private String email, password;
private ProgressBar progressBar;
public LoginTask(ProgressBar progressBar, String email, String password) {
this.progressBar = progressBar;
this.email = email;
this.password = password;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.setVisibility(View.VISIBLE);
}
private HttpURLConnection loginConnection(String email, String encPass)
{
return Connection.getConnection(Links.LOGIN_SCRIPT, "email=" + email + "&password=" + encPass);
}
private HttpURLConnection saltConnection(String email) {
return Connection.getConnection(Links.GET_SALT, "request_salt=set&request_email=" + email);
}
private HttpURLConnection existsConnection(String email) {
return Connection.getConnection(Links.USER_EXISTS + "?email=" + email);
}
@Override
protected Boolean doInBackground(String... info) {
try {
String existString = Connection.getStringFromConnection(existsConnection(email));
int existInt = Integer.parseInt(existString);
if (existInt == Connection.SUCCESS) {
String saltString = Connection.getStringFromConnection(saltConnection(email));
JSONObject saltJson = new JSONObject(saltString);
String salt = saltJson.getString("salt"); //Perfect
if (salt.length() > 0) {
String encPass = Utils.SHA256(password + salt);
JSONObject encPassObj = new JSONObject();
encPassObj.put("email", email);
encPassObj.put("encPass", encPass);
publishProgress(encPassObj);
if (encPass.length() > 0) {
String loginString = Connection.getStringFromConnection(loginConnection(email, encPass));
int logInt = Integer.parseInt(loginString);
if (logInt == Connection.SUCCESS) {
//Globals.user = new User(email, encPass);
return true;
} else {
return false;
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
@Override
protected void onProgressUpdate(JSONObject... values) {
super.onProgressUpdate(values);
try {
JSONObject object = values[0];
setEmail(object.getString("email"));
setPassword(object.getString("encPass"));
preferences.saveLoginDetails(object.getString("email"), object.getString("encPass"));
} catch (JSONException e) {
e.printStackTrace();
}
}
//UI
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
progressBar.setVisibility(View.INVISIBLE);
}
}
LoginTask 将根据成功登录 return 真值或假值,电子邮件和加密密码将用于在全局 class.
示例:
public class Global {
public static User user = new User(email, password);
}
我这里唯一的问题是用户的封装 class。我该如何改进它?
由于您的应用程序只有一个用户,因此您可以创建一个非常简单的 class,其中包含只能初始化一次的静态字段。
快速示例:
public class UserUtil {
private static String email;
private static int UID;
//etc
private static boolean initialized=false;
static public void initUserDetails(String email, int uid,//etc){
if (initialized==true)
throw new IllegalStateException("Error, User has already been initialized");
this.email=email;
this.UID=uid;
//etc
initialized=true;
}
//static public getters for private variables
}
试试这个... 将数据存储到本地数据库。同样通过本地数据库,您不需要一次又一次地下载数据。
如果您只有一个用户,那么您需要将您的 class 设置为单例 class。这样你就知道 class 只有一个实例,并且每个 activity 访问它都将使用同一个对象。
看这道题:Creating an Object accessible by all Activites in Android
所以假设我们创建了一个 Singleton class,如下所示:
public class SessionUser {
private static SessionUser instance = null;
protected SessionUser() {
// Exists only to defeat instantiation.
}
public static SessionUser getInstance() {
if(instance == null) {
instance = new SessionUser();
}
return instance;
}
private boolean isUserInSession()
{
//validation code
return isInSession;
}
}
你可以像这样在任何 class 中使用它:
//Some code
if (!SessionUser.getInstance().isUserInSession())
{
//Go to login
}
//More code