- 后端部分我就不细说了,只要是采用单点登录服务器的方式来验证
- 记住密码,采用了微信开源的MMKV,来存储账号与密码当然你也可以用安卓自带的
- MMKV:https://github.com/Tencent/MMKV
- 安卓UI框架采用QMUI,地址:https://qmuiteam.com/android
- 安卓请求框架:OKHTTP
implementation 'com.tencent:mmkv-shared:1.2.13'
implementation("com.squareup.okhttp3:okhttp:4.10.0")
implementation 'com.qmuiteam:qmui:2.0.0-alpha10'
2.2 主要布局文件
2.3 JAVA代码
package com.shu.Activity;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.JsonToken;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;
import com.shu.Common.SysConfig;
import com.shu.Constant.UrlConstant;
import com.shu.Interceptor.LoggingInterceptor;
import com.shu.R;
import com.shu.Utils.EditTextClearUtils;
import com.tencent.mmkv.MMKV;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class LoginActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "LoginActivity";
private Button login_btn;
private CheckBox check_btn;
private EditText user_text, password_text;
private ImageView user_delete, password_delete;
private final int SUCCESS_FLAG = 1;
private final int FAIL_FLAG = 3;
private final int ERROR_FLAG = 2;
private static String msg = null;
private final String USERNAME = "USERNAME";
private final String PASSWORD = "PASSWORD";
private final String REMEMBER = "REMEMBER";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MMKV.initialize(this);
// 设置全局变量
SysConfig.setMmkv(MMKV.defaultMMKV());
setContentView(R.layout.activity_login);
login_btn = findViewById(R.id.btn_login);
check_btn = findViewById(R.id.cb_checkbox);
user_text = findViewById(R.id.et_userName);
password_text = findViewById(R.id.et_password);
user_delete = findViewById(R.id.iv_unameClear);
password_delete = findViewById(R.id.iv_pwdClear);
// 监听是否有删除按钮
EditTextClearUtils.addClearListener(user_text, user_delete,check_btn);
EditTextClearUtils.addClearListener(password_text, password_delete,check_btn);
// 设置监听事件
login_btn.setOnClickListener(this);
// 复选框点击事件
check_btn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
SysConfig.getMmkv().encode(USERNAME, user_text.getText().toString());
SysConfig.getMmkv().encode(PASSWORD, password_text.getText().toString());
SysConfig.getMmkv().encode(REMEMBER, true);
} else {
SysConfig.getMmkv().remove(USERNAME);
SysConfig.getMmkv().remove(PASSWORD);
SysConfig.getMmkv().remove(REMEMBER);
}
}
});
// 是否记住密码
if (SysConfig.getMmkv().decodeBool(REMEMBER)) {
user_text.setText(SysConfig.getMmkv().decodeString(USERNAME));
password_text.setText(SysConfig.getMmkv().decodeString(PASSWORD));
check_btn.setChecked(true);
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_login) {
if (user_text.getText().toString().equals("")) {
final QMUITipDialog tipDialog;
tipDialog = new QMUITipDialog.Builder(LoginActivity.this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_INFO)
.setTipWord("账号不能为空!")
.create();
tipDialog.show();
user_text.postDelayed(new Runnable() {
@Override
public void run() {
tipDialog.dismiss();
}
}, 2000);
} else if (password_text.getText().toString().equals("")) {
final QMUITipDialog tipDialog;
tipDialog = new QMUITipDialog.Builder(LoginActivity.this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_INFO)
.setTipWord("密码不能为空!")
.create();
tipDialog.show();
password_text.postDelayed(new Runnable() {
@Override
public void run() {
tipDialog.dismiss();
}
}, 2000);
} else {
login(user_text.getText().toString(), password_text.getText().toString());
}
}
}
public void login(String username, String password) {
try {
// Okhttp客服端
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new LoggingInterceptor())
.callTimeout(5000, TimeUnit.MILLISECONDS)
.readTimeout(5000, TimeUnit.MILLISECONDS)
.writeTimeout(5000, TimeUnit.MILLISECONDS)
.build();
// post请求体
RequestBody formBody = new FormBody.Builder()
.add("username", username)
.add("password", password)
.add("grant_type", "password")
.add("scope", "all")
.build();
// 构造request请求
Request request = new Request.Builder()
.url(UrlConstant.AUTH_URL)
.post(formBody)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addHeader("Authorization", "Basic Y2xpZW50OmVhc29u")
.build();
//响应结果
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
try {
JSONObject value = (JSONObject) new JSONTokener(response.body().string().trim()).nextValue();
if (value.length()<=3) {
msg = value.getString("msg");
Message message = new Message();
//Message对象调用what字段
message.what = FAIL_FLAG;
//发送消息
handler.sendMessage(message);
} else if ( value.length()>3) {
Message message = new Message();
//Message对象调用what字段
message.what = SUCCESS_FLAG;
//发送消息
handler.sendMessage(message);
} else {
onFailure(call, null);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Message message = new Message();
//Message对象调用what字段
message.what = ERROR_FLAG;
//发送消息
handler.sendMessage(message);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public void alterSuccess() {
final QMUITipDialog tipDialog;
tipDialog = new QMUITipDialog.Builder(LoginActivity.this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_SUCCESS)
.setTipWord("登录成功")
.create();
tipDialog.show();
login_btn.postDelayed(new Runnable() {
@Override
public void run() {
tipDialog.dismiss();
}
}, 2000);
}
public void alterFail() {
final QMUITipDialog tipDialog;
tipDialog = new QMUITipDialog.Builder(LoginActivity.this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_FAIL)
.setTipWord(msg)
.create();
tipDialog.show();
login_btn.postDelayed(new Runnable() {
@Override
public void run() {
tipDialog.dismiss();
}
}, 2000);
}
public void alterError() {
final QMUITipDialog tipDialog;
tipDialog = new QMUITipDialog.Builder(LoginActivity.this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_FAIL)
.setTipWord("服务器连接失败!请检查网络情况!")
.create();
tipDialog.show();
login_btn.postDelayed(new Runnable() {
@Override
public void run() {
tipDialog.dismiss();
}
}, 2000);
}
private Handler handler = new Handler() {
@Override
//重写handleMessage()方法,接收sendMessage()方法传过来的message
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case SUCCESS_FLAG:
alterSuccess();
return;
case ERROR_FLAG:
alterError();
return;
case FAIL_FLAG:
alterFail();
}
}
};
}
2.4 全局变量
package com.shu.Common;
import com.tencent.mmkv.MMKV;
public class SysConfig {
// 全局MMKV
private static MMKV mmkv;
public static MMKV getMmkv() {
return SysConfig.mmkv;
}
public static void setMmkv(MMKV mmkv) {
SysConfig.mmkv = mmkv;
}
}
2.5 工具类
package com.shu.Utils;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import com.shu.Common.SysConfig;
public class EditTextClearUtils {
public static void addClearListener(EditText et, ImageView iv, CheckBox checkBox) {
et.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
//如果有输入内容长度大于0那么显示clear按钮
String str = s + "";
if (s.length() > 0) {
iv.setVisibility(View.VISIBLE);
} else {
iv.setVisibility(View.INVISIBLE);
SysConfig.getMmkv().remove("USERNAME");
SysConfig.getMmkv().remove("PASSWORD");
SysConfig.getMmkv().remove("REMEMBER");
}
}
});
iv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
et.setText("");
checkBox.setChecked(false);
}
});
}
}
到此我们的代码就编写完成了。
源码地址:https://github.com/Eason-shu/Android-Demo
喜欢或对你有用,请帮我点个star,谢谢。。。。。。



