前言

我们在开发安卓App时难免要与服务器打交道,尤其是对于用户账号信息的注册与登录更是每个android开发人员必须掌握的技能,本文将对客户端的注册/登录功能的实现进行分析,不到之处还请指出。

在这里我们仅讨论客户端如何请求服务器进行注册,而服务器在收到客户端请求后进行的一系列操作并不在本文所述范围内,有兴趣大家可以参考

请求服务器

客户端在进行用户信息的注册和登录时一般使用post请求(携带参数)去服务器。以volley框架请求服务器为例,真正与服务器进行交互的就是如下代码:

StringRequest request=new StringRequest(Method.POST, url, new Listener<String>() {//请求成功@Overridepublic void onResponse(String s) {//执行请求成功的回调callback.onSuccess()}}, new ErrorListener() {//请求错误@Overridepublic void onErrorResponse(VolleyError volleyError) {//执行请求失败的回调callback.onFailure()}}){//携带参数(Map集合)@Overrideprotected Map<String, String> getParams() throws AuthFailureError {return parames;}};//将请求添加到请求队列中Volley.newRequestQueue(context).add(request);

当然,我们在请求服务器成功或失败时应该设置相应的回调方法,让我们能够进行一些操作。

  • callback.onSuccess() //请求成功的回调

    1.保存用户注册信息(SP中和Application中)
    2.跳转到主页面
    
  • callback.onFailure() //请求失败的回调

    1.提示错误信息
    

下面通过一个具体的demo来介绍
(声明:此demo为阿福老师IT蓝豹App的代码截取)

注:我们在与服务器进行交互时,必须按照规定的接口和规则进行请求,这里使用的是IT蓝豹App中的服务器,服务器的注册接口数据格式如下

1.url:http://www.itlanbao.com/api/app/users/user_register_Handler.ashx2.参数说明nickname       必须有    昵称email          必须有    邮箱password       必须有    密码accesstoken    必须有    签名md5(nickname+email+password+"双方平台约定公钥")3.请求方式:POST4.返回值格式:成功{"ret":0,"errcode":0,"msg":"接口调用成功","data":{"userid":"16489","email":"nnn@aaa.com","nickname":"duss","userhead":"http://img.itlanbao.com/avatar.png"}   }失败{"ret":1,"errcode":1,"msg":"接口调用失败"}

demo演示

主要实现代码(demo会在文章最后给出)

1.注册页面中(RegisterActivity),点击注册按钮

registBtn.setOnClickListener(new Button.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub//获得用户输入的信息String nick = loginNick.getText().toString();String emailStr = email.getText().toString();String passwordStr = password.getText().toString();if (!TextUtils.isEmpty(nick) &&!TextUtils.isEmpty(emailStr)&& !TextUtils.isEmpty(passwordStr)) {if (Utils.isEmail(emailStr)) {//验证邮箱格式是否符合//调用RequestApiData中的getRegistData()方法进行注册,传入用户输入的昵称,邮箱、密码,以及解析数据的bean对象和callback对象(回调到自身)RequestApiData.getInstance().getRegistData(nick, emailStr, passwordStr,AnalyticalRegistInfo.class, RegisterActivity.this);} else {Toast.makeText(RegisterActivity.this, "输入邮箱有误", Toast.LENGTH_SHORT).show();}} else {Toast.makeText(RegisterActivity.this, "输入信息未完全", Toast.LENGTH_SHORT).show();}}});

注意:这个注册的方法中,我们传入的最后一个参数是回调的对象,这里我们传入的是RegisterActivity自身,所以它需要实现HttpResponeCallBack接口

RequestApiData.getInstance().getRegistData(nick, emailStr, passwordStr,AnalyticalRegistInfo.class, RegisterActivity.this);

2.请求服务器的回调接口(HttpResponeCallBack)

public interface HttpResponeCallBack {public void onResponeStart(String apiName);/*** 此回调只有调用download方法下载数据时才生效* * @param apiName* @param count* @param current*/public void onLoading(String apiName, long count, long current);public void onSuccess(String apiName, Object object);public void onFailure(String apiName, Throwable t, int errorNo, String strMsg);}

3.网络接口类(RequestApiData)

public class RequestApiData {private static RequestApiData instance = null;private HttpResponeCallBack mCallBack = null;//创建接口对象public static RequestApiData getInstance() {if (instance == null) {instance = new RequestApiData();}return instance;}/*** 4.6注册用户接口* @param nickname  昵称* @param email 邮箱* @param password 密码* @param clazz  数据返回的解析对象* @param callback 回调* 特别要注意参数位置不能变要根据文档来* 请求方式:POST*/public void getRegistData(String nickname,String email,String password, Class<AnalyticalRegistInfo> clazz,HttpResponeCallBack callback) {mCallBack = callback;//这是每一个接口的唯一标示String tagUrl = UrlConstance.KEY_REGIST_INFO;//注册接口//将注册的信息保存在map中(须和服务器端一致)HashMap<String, String> parameter = new HashMap<String, String>();parameter.put("nickname", nickname);parameter.put("email",email);parameter.put("password",password);//拼接参数信息,昵称,邮箱,密码,公钥,并用md5进行加密StringBuilder builder = new StringBuilder();builder.append(nickname);builder.append(email);builder.append(password);builder.append(UrlConstance.PUBLIC_KEY);parameter.put(UrlConstance.ACCESSTOKEN_KEY,MD5Util.getMD5Str(builder.toString()));//调用RequestManager的post方法,请求服务器RequestManager.post(UrlConstance.APP_URL,tagUrl, parameter, clazz, callback);}
}

4.网络请求处理的类(RequestManager)

public class RequestManager {private static RequestQueue mRequestQueue;private static ImageLoader mImageLoader;private synchronized static void initRequestQueue() {if (mRequestQueue == null) {//创建一个请求队列(使用Volley框架)mRequestQueue = Volley.newRequestQueue(ItLanbaoLibApplication.getInstance());}}/*** 添加请求到请求队列中* @param request* @param tag*/private static void addRequest(Request<?> request, Object tag) {if (tag != null) {request.setTag(tag);}mRequestQueue.add(request);}/*** post 请求数据** @param app_url     公共的接口前缀 http://www.itlanbao.com/api/app/* @param tag_url     接口名称,eg:users/user_register_Handler.ashx(注册接口)* @param parameter  请求参数封装对象* @param clazz      返回数据封装对象,如果传null,则直接返回String* @param callback   接口回调监听*/public static <T> void post(final String app_url, final String tag_url, final HashMap<String, String> parameter, Class<T> clazz,final HttpResponeCallBack callback) {//发送post请求服务器post(app_url, tag_url, parameter, clazz, callback, Priority.NORMAL);}/*** post 请求数据** @param app_url    路径* @param url        接口名称* @param parameter  请求参数封装对象* @param clazz      返回数据封装对象,如果传null,则直接返回String* @param callback   接口回调监听* @param priority   指定接口请求线程优先级*/public static <T> void post(final String app_url, final String url, final HashMap<String, String> parameter, final Class<T> clazz,final HttpResponeCallBack callback, Priority priority) {if (callback != null) {callback.onResponeStart(url);//回调请求开始}//初始化请求队列initRequestQueue();//将公共的接口前缀和接口名称拼接//eg:拼接成注册的接口  http://www.itlanbao.com/api/app/users/user_register_Handler.ashxStringBuilder builder = new StringBuilder(app_url);builder.append(url);{// 检查当前网络是否可用final NetworkUtils networkUtils = new NetworkUtils(ItLanbaoLibApplication.getInstance());if (!networkUtils.isNetworkConnected() && android.os.Build.VERSION.SDK_INT > 10) {if (callback != null) {callback.onFailure(url, null, 0, "网络出错");//回调请求失败return;}}}/*** 使用Volley框架真正去请求服务器* Method.POST:请求方式为post* builder.toString():请求的链接* Listener<String>:监听*/StringRequest request = new StringRequest(Method.POST, builder.toString(),new Listener<String>() {@Overridepublic void onResponse(String response) {// TODO Auto-generated method stubtry {if (response != null && callback != null) {Gson gson = new Gson();//回调请求成功,传入url和解析的对象callback.onSuccess(url, gson.fromJson(response, clazz));}} catch (Exception e) {// TODO: handle exceptionif (callback != null) {//回调请求失败--解析异常callback.onFailure(url, e, 0, "解析异常");return;}}}}, new ErrorListener() {//请求出错的监听@Overridepublic void onErrorResponse(VolleyError error) {if (callback != null) {if (error != null) {callback.onFailure(url, error.getCause(), 0,error.getMessage());} else {callback.onFailure(url, null, 0, "");}}}}) {//post请求的参数信息protected Map<String, String> getParams() {return getPostApiParmes(parameter);}};//添加请求到请求队列中addRequest(request, url);}/** post参数* * ts:时间戳 sign: 接口签名 parms = 按文档参数拼接 parm[0]+ … + parm[n-1] sign =* md5(parms+"双方平台约定公钥")*/private static ApiParams getPostApiParmes(final HashMap<String, String> parameter) {ApiParams api = new ApiParams();for (Entry<String, String> entry : parameter.entrySet()) {api.with(entry.getKey(), entry.getValue());}return api;}}

5.在请求服务器成功/失败后会执行回调方法,而我们传入的callback对象是自身(RegisterActivity),所以现在我们回到注册页面

    @Overridepublic void onResponeStart(String apiName) {// TODO Auto-generated method stubToast.makeText(RegisterActivity.this, "正在请求数据...", Toast.LENGTH_SHORT).show();}@Overridepublic void onLoading(String apiName, long count, long current) {Toast.makeText(RegisterActivity.this, "Loading...", Toast.LENGTH_SHORT).show(); }@Overridepublic void onSuccess(String apiName, Object object) {// TODO Auto-generated method stub//注册接口if (UrlConstance.KEY_REGIST_INFO.equals(apiName)) {if (object != null && object instanceof AnalyticalRegistInfo) {AnalyticalRegistInfo info = (AnalyticalRegistInfo) object;String successCode = info.getRet();//请求成功if (successCode.equals(Constant.KEY_SUCCESS)) {UserBaseInfo baseUser = new UserBaseInfo();baseUser.setEmail(info.getEmail());baseUser.setNickname(info.getNickname());baseUser.setUserhead(info.getUserhead());baseUser.setUserid(String.valueOf(info.getUserid()));ItLanBaoApplication.getInstance().setBaseUser(baseUser);UserPreference.save(KeyConstance.IS_USER_ID, String.valueOf(info.getUserid()));UserPreference.save(KeyConstance.IS_USER_ACCOUNT, info.getEmail());UserPreference.save(KeyConstance.IS_USER_PASSWORD, password.getText().toString());Intent intent = new Intent(RegisterActivity.this, MainActivity.class);RegisterActivity.this.startActivity(intent);Toast.makeText(RegisterActivity.this, "注册成功...", Toast.LENGTH_SHORT).show();RegisterActivity.this.finish();} else {Toast.makeText(RegisterActivity.this, "注册失败", Toast.LENGTH_SHORT).show();}}}}@Overridepublic void onFailure(String apiName, Throwable t, int errorNo, String strMsg) {Toast.makeText(RegisterActivity.this, "Failure", Toast.LENGTH_SHORT).show();}

至此,安卓客户端的注册功能就实现了,下一篇中将会介绍登录和自动登录的实现

Android客户端实现注册/登录详解(二)

demo下载地址
http://download.csdn.net/detail/benhuo931115/9483031

Android客户端实现注册/登录详解(一)相关推荐

  1. Android 微信第三方绑定登录详解

    赢第三方微信登录跟微信支付差别不是很大,下面一一为大家分享一下,欢迎吐槽指正. 接入微信的支付要第一步添加微信支付官方的包libammsdk.jar 一.配置文件Androidmanifest < ...

  2. php注册登录详解_实例讲解php用户注册与登录页面

    这周做了个php的简单实例,算是学了这么久php语法的一次综合应用吧,感觉前面学的东西都不知道怎么用,不看教程还真做不出来.本来想把它写在网页弹出层上的,这样看起来更像是一个用户登录框,但是看了弹出层 ...

  3. Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能

    Android高效率编码-第三方SDK详解系列(二)--Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能 我的本意是第二篇写Mob的shareSD ...

  4. Android第三方登录详解2

    接着Android第三方登录详解1讲 1.找到友盟  文档中心 2.找到 3.将 UMSocialService mController = UMServiceFactory.getUMSocialS ...

  5. Android高效率编码-第三方SDK详解系列(三)——JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送

    Android高效率编码-第三方SDK详解系列(三)--JPush推送牵扯出来的江湖恩怨,XMPP实现推送,自定义客户端推送 很久没有更新第三方SDK这个系列了,所以更新一下这几天工作中使用到的推送, ...

  6. Android Telephony分析(五) ---- TelephonyRegistry详解

    本文紧接着上一篇文章<Android Telephony分析(四) -- TelephonyManager详解 >的1.4小节.  从TelephonyRegistry的大部分方法中:  ...

  7. iPhone和Android的WEB应用开发详解

    iPhone和Android的WEB应用开发详解 在我们现在的生活中,移动设备的作用日益重要.我们使用它们进行交流.我们使用它们进行导航.我们甚至可以将它们用作方便的手电筒.面向 iPhone 和 A ...

  8. 《Android多媒体应用开发实战详解:图像、音频、视频、2D和3D》——1.3节搭建Android应用开发环境...

    本节书摘来自异步社区<Android多媒体应用开发实战详解:图像.音频.视频.2D和3D>一书中的第1章,第1.3节搭建Android应用开发环境,作者 王石磊 , 吴峥,更多章节内容可以 ...

  9. Android中的四大组件详解

    Android中的四大组件详解 我们都知道Android系统应用层框架中,为开发者提供了四大组件来便于应用的开发,它们是Activity.Service.BroadcastReceiver.Conte ...

最新文章

  1. 「分布式」艺术创作:20分钟+1080显卡,这个AI就能创造复杂作品 | 开源
  2. 皮一皮:千万别得罪一个文科生...
  3. Python使用@property方法改变方法为参数
  4. VTK:可视化之ReverseAccess
  5. 程序员应该知道的二十三种设计模式
  6. 【好文推荐】java模板引擎性能
  7. “控本焦虑”的工程企业 用钉钉宜搭找到了低成本数字化的“捷径”
  8. 文件上传之Apache commons fileupload使用
  9. ehcache缓存共享(rmi方法)
  10. Mac 10.12安装Windows远程桌面工具Microsoft Remote Desktop
  11. 阅读STC(宏晶)公司的芯片手册知识
  12. PayPal提现到美国账户收35美元怎么办?最新3种解决办法!
  13. 计算机如何从光盘启动不了,电脑如何设置光驱启动?开机设置光驱为第一启动的步骤...
  14. SpringBoot 之 @Transaction注解的类级别和方法级别的区别
  15. 掘金 AMA:听蚂蚁金服高级技术专家-- 章耿谈微服务、架构、日志那些事
  16. 消防报警图形显示装置linux,消防中控-消防控制室图形显示装置状态识别及操作...
  17. 软件测试常用的性能测试指标,7个常用的网络性能测试指标
  18. 计算机双工模式,windows10系统如何设置网络双工模式?
  19. Nestjs中的守卫
  20. k8s 1.17.3 二进制部署

热门文章

  1. 匹配身高测试软件,测试|从身高测你和Ta是否天生一对
  2. Airfoil for mac(无线音乐同步管理器)
  3. 【libdatachannel】streamer与js客户端本机联调3 client流程
  4. 将字符串按指定的符号分割为集合或数组
  5. 跟随B站视频学Python爬虫过程(6):豆瓣电影TOP250并存Excel(使用urllib, bs, re, xlwt库)
  6. 如何在word表格中添加删除线,划去不想要的部分?
  7. 2022安全员-B证复训题库及在线模拟考试
  8. 【整理】屏幕色彩与分辨率区别,PPI的概念,IPS屏与TFT屏
  9. Vue3通透教程【八】获取DOM、操作组件
  10. Java实现IPv4转地址,基于纯真数据库的一种高性能实现