Android之SqliteDatabase(MVP模式)实现用户登录注册功能
16lz
2021-01-26
Android之SqliteDatabase(MVP模式)实现用户登录注册功能
用户登录以及注册功能的普遍使用就不用我说了,任何一款应用软件基本都具有登录和注册功能,今天通过前面的学习,我写了一个小demo,就是使用MVP模式写一个用户登录和注册的功能。有关MVP模式我就不做讲解了,通常来说很多实现的登录或者注册功能都是使用MVC的模式来实现的,今天我将采用MVP模式来实现这个小demo,主要是为了巩固数据库部分的知识点,然后让大家熟悉MVP这种模式,看看MVP模式的优势在哪里(其实MVP最主要的就是达到完全解耦,不同的层实现不同的功能,互不影响)。
案例的主要功能:
1. 用户登录
2. 用户注册
模拟场景:当用户点击登录按钮时,模式了一个延时3秒的操作,相当于从服务器获取用户登录信息,3秒后返回登录结果。注册也是一样
程序整体结构图:
老样子,主要功能在程序中注释
view层:
ViewInter.java
/** * view层所有的功能 */public interface ViewInter { //获取用户名 String getName(); //获取用户密码 String getPass(); //清除界面中编辑框里的名字 void clearUserName(); //清除界面中编辑框里的密码 void clearUserPass(); //显示进度条 void showLoading(); //隐藏进度条 void hideLoading(); /** * 提示用户登录或注册成功后的状态 * @param user 用户信息 * @param tag 表示登录或注册提示 */ void successHint(User user, String tag); /** * 提示用户登录或注册失败后的状态 * @param user 用户信息 * @param tag 表示登录或注册提示 */ void failHint(User user, String tag);}
Login.java
public class Login extends AppCompatActivity implements ViewInter{ private EditText mUserName;//用户名控件 private EditText mUserPwd;//用户密码控件 private Button mBtnLogin;//登录按钮 private Button mBtnClear;//清除按钮 private ProgressBar mProBar;//进度条 private TextView mRegister;//点我注册控件 private Presenter presenter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); //初始化控件 initView(); //初始化事件 event(); //建立与presenter层的关系,创建presenter对象 presenter = new Presenter(this, Login.this); } private void initView() { mUserName = (EditText) findViewById(R.id.user_name); mUserPwd = (EditText) findViewById(R.id.user_pwd); mBtnLogin = (Button) findViewById(R.id.btn_login); mBtnClear = (Button) findViewById(R.id.btn_clear); mProBar = (ProgressBar) findViewById(R.id.progressBar); mRegister = (TextView) findViewById(R.id.mRegister); } private void event() { /** * 登录响应事件 */ mBtnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //告诉presenter层,我需要登录操作 presenter.login(); } }); /** * 清除响应事件 */ mBtnClear.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //告诉presenter层,我需要清除操作 presenter.clear(); } }); /** * 点击注册响应事件,跳转到注册界面 */ mRegister.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(Login.this,Register.class); startActivity(intent); finish(); } }); } @Override public String getName() { return mUserName.getText().toString(); } @Override public String getPass() { return mUserPwd.getText().toString(); } @Override public void clearUserName() { mUserName.setText(""); } @Override public void clearUserPass() { mUserPwd.setText(""); } @Override public void showLoading() { mProBar.setVisibility(View.VISIBLE); } @Override public void hideLoading() { mProBar.setVisibility(View.GONE); } @Override public void successHint(User user,String tag) { Toast.makeText(this,"用户" + user.getUserName() + tag + "成功",Toast.LENGTH_SHORT).show(); } @Override public void failHint(User user,String tag) { Toast.makeText(this,"用户" + user.getUserName() + tag + "失败,密码或账号不正确,maybe not this user",Toast.LENGTH_LONG).show(); }}
Register.java
public class Register extends AppCompatActivity implements ViewInter { private EditText mUserName; private EditText mUserPwd; private Button mBtnRegister; private Button mBtnClear; private ProgressBar mProBar; private TextView mTvLogin;//点击注册控件 private Presenter presenter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); initView(); event(); presenter = new Presenter(this, Register.this); } private void initView() { mUserName = (EditText) findViewById(R.id.user_name); mUserPwd = (EditText) findViewById(R.id.user_pwd); mBtnRegister = (Button) findViewById(R.id.btn_register); mBtnClear = (Button) findViewById(R.id.btn_clear); mProBar = (ProgressBar) findViewById(R.id.progressBar); mTvLogin = (TextView) findViewById(R.id.mTvLogin); } private void event() { /** * 注册功能 */ mBtnRegister.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { presenter.register(); } }); /** * 清除功能 */ mBtnClear.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { presenter.clear(); } }); /** * 启动登录界面 */ mTvLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(Register.this,Login.class); startActivity(intent); finish(); } }); } @Override public String getName() { return mUserName.getText().toString(); } @Override public String getPass() { return mUserPwd.getText().toString(); } @Override public void clearUserName() { mUserName.setText(""); } @Override public void clearUserPass() { mUserPwd.setText(""); } @Override public void showLoading() { mProBar.setVisibility(View.VISIBLE); } @Override public void hideLoading() { mProBar.setVisibility(View.GONE); } @Override public void successHint(User user, String tag) { Toast.makeText(this, "用户" + user.getUserName() + tag + "成功", Toast.LENGTH_SHORT).show(); } @Override public void failHint(User user, String tag) { Toast.makeText(this, "用户" + user.getUserName() + tag + "失败,已存在该用户", Toast.LENGTH_SHORT).show(); }}
presenter层:
Presenter.java
public class Presenter { //view层的控件,对view层进行操作 ViewInter viewInter; //模型层的控件,对model层进行操作 ModelInter modelInter; public Presenter(ViewInter viewInter, Context context) { this.viewInter = viewInter; modelInter = new ModelImp(context); } /** * 注册功能 */ public void register() { //显示进度条 viewInter.showLoading(); //控制层开始处理数据,拿到视图层的name,pass之后,进行注册操作 //OnRegisterListener匿名内部类 modelInter.register(viewInter.getName(), viewInter.getPass(), new OnRegisterListener() { /** * 如果注册成功模型层就会调用该方法 * 其中的handler表示模拟延时3秒响应操作 * @param user 返回已经注册的用户信息 */ @Override public void registerSuccess(final User user) { Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { //隐藏进度条 viewInter.hideLoading(); //返回成功状态信息 viewInter.successHint(user,TAG); } }, 3000); } /** * 如果注册失败模型层就会调用该方法 * 其中的handler表示模拟延时3秒响应操作 * @param user 返回未注册的用户信息 */ @Override public void registerFail(final User user) { Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { //隐藏进度条 viewInter.hideLoading(); //返回失败状态信息 viewInter.failHint(user,TAG); } }, 3000); } }); } /** * 清除功能 */ public void clear() { viewInter.clearUserName(); viewInter.clearUserPass(); } /** * 登录功能,其基本实现和注册一样,只是模型层处理的逻辑不一样 */ public void login(){ viewInter.showLoading(); modelInter.login(viewInter.getName(), viewInter.getPass(), new OnLoginListener() { @Override public void loginSuccess(final User user) { Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { viewInter.hideLoading(); viewInter.successHint(user,TAG); } },3000); } @Override public void loginFail(final User user) { Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { viewInter.hideLoading(); viewInter.failHint(user,TAG); } },3000); } }); }}
model层:
ModelInter.java
/** * 所有数据处理操作功能都定义在这个接口中,方便扩展 */public interface ModelInter { /** * 注册操作 * * @param name 用户名 * @param pass 用户密码 * @param listener 回调事件,如果成功调用注册成功方法,失败调用注册失败方法 */ void register(String name, String pass, OnRegisterListener listener); /** * 登录操作 * * @param name 用户名 * @param pass 用户密码 * @param listener 回调事件,如果成功调用登录成功方法,失败调用登录失败方法 */ void login(String name, String pass, OnLoginListener listener);}
OnLoginListener.java
/** * 登录成功或失败的接口 */public interface OnLoginListener { //表示登录标签 String TAG = "登录"; /** * 登录成功,传递了用户信息 * * @param user */ void loginSuccess(User user); /** * 登录失败,传递了用户信息 * * @param user */ void loginFail(User user);}
OnRegisterListener.java
/** * 注册成功或失败的接口 */public interface OnRegisterListener { //表示注册标签 String TAG = "注册"; /** * 注册成功,传递了用户信息 * * @param user */ void registerSuccess(User user); /** * 注册失败,传递了用户信息 * * @param user */ void registerFail(User user);}
ModelIpm.java
/** * 整体的逻辑实现,判断是否登录成功,失败 */public class ModelImp implements ModelInter { //获取数据库管理类,对数据库进行操作 private UserDao userDao; public ModelImp(Context context){ userDao = new ImpUserDao(context); } /** * 注册逻辑实现 * @param name 用户名 * @param pass 用户密码 * @param listener 回调事件,如果成功调用注册成功方法,失败调用注册失败方法 */ @Override public void register(String name, String pass, OnRegisterListener listener) { //将用户名和密码封装到user中 User user = new User(name,pass); //数据库不存在该用户注册成功,否则注册失败 if(userDao.isExistsUser(user)){ listener.registerFail(user); }else{ userDao.addUser(user); listener.registerSuccess(user); } } /** * 登录逻辑实现 * @param name 用户名 * @param pass 用户密码 * @param listener 回调事件,如果成功调用登录成功方法,失败调用登录失败方法 */ @Override public void login(String name, String pass, OnLoginListener listener) { User user = new User(name,pass); //判断是否登录成功 if(userDao.isLoginSuccess(user)){ listener.loginSuccess(user); }else{ listener.loginFail(user); } }}
dao:(数据库的操作工具类)
UserDao.java
public interface UserDao { void addUser(User user);//添加新用户 void delteUserByName(String name);//删除用户 void updateUserPwd(String name, String pass);//通过同户名修改密码 User queryUserByName(String name);//通过用户名查找用户 boolean isExistsUser(User user);//判断是否存在重复用户 boolean isLoginSuccess(User user);}
ImpUserDao.java
/*** 在这个方法中,我都采用了两种对数据进行操作的方法,一种是sql语句,一种是直接调用封装好了的方法* 哪种方式都可以,看个人爱好*/public class ImpUserDao implements UserDao { private DBHelper dbHelper; private SQLiteDatabase database; private ContentValues values; public ImpUserDao(Context context) { dbHelper = new DBHelper(context); } /** * 添加新用户 * @param user 注册的用户信息 */ @Override public void addUser(User user) { database = dbHelper.getWritableDatabase(); //方式一:sql语句操作数据库// String sql = "insert into users(uName,uPass) values(?,?)";// database.execSQL(sql,new Object[]{user.getUserName(),user.getUserPass()}); //方法二:封装的api操作,直接操作方法即可 values = new ContentValues(); values.put(DBHelper.COLNUMNAME, user.getUserName()); values.put(DBHelper.COLNUMPASS, user.getUserPass()); database.insert(DBHelper.TABLENAME, null, values); database.close(); } /** * 根据名字删除用户 * * @param name 要删除用户的名字 */ @Override public void delteUserByName(String name) { database = dbHelper.getWritableDatabase(); //方式一:sql语句操作数据库// String sql = "delete from " + DBHelper.TABLENAME + " where " + DBHelper.COLNUMNAME + " = ?";// database.execSQL(sql,new Object[]{name}); //方法二:封装的api操作,直接操作方法即可 database.delete(DBHelper.TABLENAME,DBHelper.COLNUMNAME + " = ?",new String[]{name}); database.close(); } /** * 更新用户密码 * * @param name 用户名 * @param pass 用户密码 */ @Override public void updateUserPwd(String name, String pass) { database = dbHelper.getWritableDatabase(); //方式一:sql语句操作数据库// String sql = "update " + DBHelper.TABLENAME + " set " + DBHelper.COLNUMPASS + " = ? where " + DBHelper.COLNUMNAME + " = ?";// database.execSQL(sql,new Object[]{pass,name}); //方法二:封装的api操作,直接操作方法即可 values = new ContentValues(); values.put(DBHelper.COLNUMPASS,pass); database.update(DBHelper.TABLENAME,values,DBHelper.COLNUMNAME + " = ?",new String[]{pass}); database.close(); } /** * 通过用户名查找用户 * * @param name */ @Override public User queryUserByName(String name) { database = dbHelper.getReadableDatabase(); //方式一:sql语句操作数据库// String sql = "select * from " + DBHelper.TABLENAME + " where " + DBHelper.COLNUMNAME + " = ?";// Cursor cursor = database.rawQuery(sql, new String[]{name}); //方法二:封装的api操作,直接操作方法即可 Cursor cursor = database.query(DBHelper.TABLENAME, null, DBHelper.COLNUMNAME + " = ?", null, null, null, null); User user = null; while(cursor.moveToNext()){ user = new User(); user.setUserName(cursor.getString(cursor.getColumnIndex(DBHelper.COLNUMNAME))); user.setUserPass(cursor.getString(cursor.getColumnIndex(DBHelper.COLNUMPASS))); } cursor.close(); return user; } /** * 判断是否存在该用户 * * @param user * @return */ @Override public boolean isExistsUser(User user) { User isExit = queryUserByName(user.getUserName()); return isExit == null ? false : true; } /** * 判断是否登录成功 * @param user 登录的用户信息 * @return */ @Override public boolean isLoginSuccess(User user) { database = dbHelper.getReadableDatabase(); //方法一:sql语句操作// String sql = "select * from " + DBHelper.TABLENAME + " where " + DBHelper.COLNUMNAME + " = ? and " + DBHelper.COLNUMPASS + " = ?";// Cursor cursor = database.rawQuery(sql, new String[]{user.getUserName(), user.getUserPass()}); //方法二:封装的api操作,直接操作方法即可 Cursor cursor = database.query(DBHelper.TABLENAME, null, DBHelper.COLNUMNAME + " = ? and " + DBHelper.COLNUMPASS + " = ?", new String[]{user.getUserName(), user.getUserPass()}, null, null, null); if(cursor.moveToFirst()){ cursor.close(); return true; } cursor.close(); return false; }}
database:(数据库封装类)
DBHelper.java
public class DBHelper extends SQLiteOpenHelper { //数据库名 public static final String DBNAME = "users.db"; //版本号 public static final int VERSION = 1; //表名 public static final String TABLENAME = "users"; //列名 public static final String COLNUMNAME = "uName"; //列名 public static final String COLNUMPASS = "uPass"; public DBHelper(Context context) { super(context, DBNAME, null, VERSION); } /** * 该方法只执行一次,首次执行创建表 * @param db */ @Override public void onCreate(SQLiteDatabase db) { String sql = "create table " + TABLENAME + "(_id integer primary key autoincrement,uName varchar(20) not null,uPass varchar(20) not null)"; db.execSQL(sql); } /** * 版本更新调用该方法 * @param db * @param oldVersion * @param newVersion */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } /** * 还原旧版本 * @param db * @param oldVersion * @param newVersion */ @Override public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { super.onDowngrade(db, oldVersion, newVersion); }}
bean:
User.java
public class User { private String userName; private String userPass; public User() { } public User(String userName, String userPass) { this.userName = userName; this.userPass = userPass; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPass() { return userPass; } public void setUserPass(String userPass) { this.userPass = userPass; } @Override public String toString() { return "User{" + "userName='" + userName + '\'' + ", userPass='" + userPass + '\'' + '}'; }}
基本的功能都已经实现了,所有的代码都在这里,关于布局的代码就不贴上 ,等下我把整个项目打包一下,需要源代码的直接自己下载就行了。对于不属性MVP模式的童鞋,可能能看懂,但是自己要去实现就有一点点麻烦了,下面看看运行的结果吧。
源码下载
更多相关文章
- Android短信Receiver优先级
- android 数据库处理及操作
- Android第十九期 - Sqlite离线存储教你写小米记事本
- Android高性能编码 - 第二篇 数据库操作
- 一切为了更贴近系统―Android中的线程模型
- Android应用程序私有目录下文件操作总结
- 回调机制在 Android(安卓)监听用户界面操作中的体现
- 几张SVG矢量图看明所有操作系统之间的演进关系
- 从破解APP开始学Android——用户登录验证