安卓实战之登录界面设计
运行环境:
windows10+ Android Studio2.3.3 +API 21
(适用android 5.0以上版本的手机)
(1)知识储备
(知识储备链接:https://blog.csdn.net/biggerchong/article/details/83015407)
Activity:表示当前手机的整个界面(一页)
OnCreate( ): 当页面被创建时被activity回调,方法中常加入初始化实现
onStart( ):当页面显示时被activity回调
onRestart( ):重新启动activity时被回调,总是在onStart()之后执行
onPause( ):快速暂停activity
onResume( ):当Activity由暂停状态恢复为活动状态时被回调
onStop( ):当页面被隐藏时被activity回调
onDestory( ):销毁activity时被回调
Intent:activity之间跳转的桥梁,直接通过putExtra( )传递/回传数据;还可以利用Bundle先对有用的数据加工,
再利用putExtra( )传递数据。(Bundle对象可以包含所有putEextra()传递的数据)
(注:Activity和Intent具体可查阅android官方文档https://developer.android.google.cn/guide/components/intents-filters)
Mob短信验证码:http://wiki.mob.com/sdk-sms-android-3-0-0/ 官方文档教学,主要用到mob自身封装的回调机制
(注意在清单xml中添加相应的权限,不然是收不到短信验证信息的)
Mysql数据库:目前Android版本强制规定用线程来使用数据库(增删改查等),防止界面线程被卡死。
(数据库的连接操作将在服务器部署部分详细讲解)
(2)项目流程
(3)界面设计
主界面 登录界面
注册界面 设置密码
(4)响应设计
1、点击登录图标:
//点击登陆
ImageButton imBtn_login=(ImageButton)findViewById(R.id.imBtn_login);
imBtn_login.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
//页面跳转,并请求获取数据
Intent intent= new Intent(MainActivity.this,LoginActivity.class);
startActivityForResult(intent,REQUESTMAIN); //会进行回调得到想要的数据
}
});
2、取回指定的数据:
//通过重写onActivityResult来取回数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
// 是否 REQ_GET_INPUT 的返回
if (requestCode == REQUESTMAIN&&resultCode == 103)
{
// 从intent中取出数据
user.userID= data.getStringExtra("userID");
user.userName= data.getStringExtra("userName");
user.userPwd= data.getStringExtra("userPwd");
user.userPhone=data.getStringExtra("userID");
user.status=Boolean.valueOf(data.getStringExtra("status"));
}
if (requestCode == REQUESTMAIN&&resultCode == 104)
{
// 从intent中取出数据
user.userPwd= data.getStringExtra("loginPwd");
user.userPhone=data.getStringExtra("loginPhone");
TextView userName=(TextView)findViewById(R.id.textView_mainName);
userName.setText(user.userPhone);
TextViewmainGrade=
(TextView)findViewById(R.id.textView_mainGrade);
mainGrade.setText(user.userPwd);
}
}
说明:
整套登录界面的总体流程大致就是按照这样一套模式来进行的,注意的是在注册完毕并且设置密码完成后页面将会按需返回,意思就是activity都存在一个栈中,创建的时候在压栈;销毁的时候在抛栈。当设置密码完毕后此界面就会自动回调onDestory( )来销毁该界面并返回到注册界面,但是这里我设置成界面不显示但数据还在往会传,当数据从注册界面传回到登录界面后,利用再销毁注册界面(只需要一个finish( )就可以了,使当前界面不显示,数据传输完毕自动或人为销毁界面)
3、优化方案:
i、采用MD5对密码加密
原理介绍:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。填充方法:在消息后面进行填充,填充第一位为1,其余为0。
(链接:http://libin52008.blog.163.com/blog/static/105327187201186981459/)
网上这种东西大部分都是你抄我,我抄你参考价值不高;这里只是简单的介绍,然后copy代码;有兴趣可以专攻哟!(网络海洋庞大,知识无穷无尽,你懂的!)
(还可以使用(AES+base64+PBE)更加高级安全的方法来加密,不过操作起来稍微复杂一些,这里就使用java自带的MD5来加密解密)
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* 采用MD5加密解密
*/
public class MyTest {
private static final String TAG = "MD5Util";
/***
* MD5加码 生成32位md5码
*/
public static String string2MD5(String inStr) {
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
} catch (Exception e) {
System.out.println(e.toString());
e.printStackTrace();
return "";
}
char[] charArray = inStr.toCharArray();
byte[] byteArray = new byte[charArray.length];
for (int i = 0; i < charArray.length; i++)
byteArray[i] = (byte) charArray[i];
byte[] md5Bytes = md5.digest(byteArray);
StringBuffer hexValue = new StringBuffer();
for (int i = 0; i < md5Bytes.length; i++) {
int val = ((int) md5Bytes[i]) & 0xff;
if (val < 16)
hexValue.append("0");
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString();
}
/**
* 加密解密算法 执行一次加密,两次解密
*/
public static String convertMD5(String inStr) {
char[] a = inStr.toCharArray();
for (int i = 0; i < a.length; i++) {
a[i] = (char) (a[i] ^ 't');
}
String s = new String(a);
return s;
}
// 测试主函数
public static void main(String args[])
{
String s = new String("shenchong");
System.out.println("原始:" + s+s.le);
System.out.println("MD5后:" + string2MD5(s));
System.out.println("加密的:" + convertMD5(s));
System.out.println("解密的:" + convertMD5(convertMD5(s))+ convertMD5(convertMD5(s)).length());
}
}
ii、实现延时自动登录
(SharePreferneces官方介绍:https://developer.android.google.cn/reference/android/content/SharedPreferences)
// 保存当前用户信息,以便下一次开机启动时加载
SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("username", username);
editor.putString("password", password);
editor.commit();
// 从配置里加载
SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
String username = sharedPref.getString("username", "");
String password = sharedPref.getString("password", "");
if(username.length() >0 && password.length() > 0)
{
// 自动填写用户名和密码
((EditText) findViewById(R.id.id_username)).setText(username);
((EditText) findViewById(R.id.id_password)).setText(password);
// 延时N毫秒后自动登录
autoLogin();
}
//延时登录
Handler msgHandler = new Handler();
// 延时后自动登录
private void autoLogin()
{
msgHandler.postDelayed(new Runnable()
{
@Override
public void run()
{
doLogin(null);
}
}, 1500);
}
iii、防止sql注入(字符转义)
password=password.replace(" ' ", " /' ");
password=password.replace(" ` ", " /` ");
利用replace()函数将String进行转义,避免MySql中` 与 ' 这些特殊字符的出现而非法进入用户信息。
(5)问题总结和完善
设计中最开始对activity跳转流程模糊导致走了很多弯路,开发过程中现有一个清晰的模块流程感,不然很难有序高效的开发。本次Login模块的开发可以拓展到很多新的知识,最关键的提高个人对activity与Intent的理解与使用,懂得什么时候activity被创建、被销毁、被启动等。
登录设计模块源码以上传github:https://github.com/SCAsMessi/JavaStudy/tree/master/CSDN/Android%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/LoginDesign/ForeignShopping
加油!欢迎评论,一起进步!