`
zhonglunshun
  • 浏览: 139538 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

一口气看完口袋微博源码(二)

阅读更多

一口气看完口袋微博源码(二)之用户登录

上一篇讲了用户的注册,上篇文章的地址:

 http://zhonglunshun.iteye.com/blog/2093938

这一篇讲用户登录,步入正题,用户登录首先要写好安卓的界面部分,既然是登录,无外乎用户名,密码,是否记住,然后就是登录按钮,ok直接上代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:background="@drawable/back"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >                           <!-- 声明垂直分布的线性布局 -->
    <LinearLayout
       android:orientation="horizontal"
       android:layout_gravity="center_horizontal"
       android:paddingTop="25px"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       >
       <TextView
           android:text="@string/tvUid"
           android:layout_width="100px"
           style="@style/text"
           android:layout_height="wrap_content"
           android:layout_gravity="center_vertical"
           />
       <EditText
           android:id="@+id/etUid"
           android:singleLine="true"
           android:layout_width="150px"
           android:layout_height="wrap_content"
           />
       </LinearLayout>
    <LinearLayout
       android:orientation="horizontal"
       android:layout_gravity="center_horizontal"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       >
       <TextView
           android:text="@string/tvPwd"
           android:layout_width="100px"
           style="@style/text"
           android:layout_height="wrap_content"
           android:layout_gravity="center_vertical"
           />
       <EditText
           android:id="@+id/etPwd"
           android:singleLine="true"
           android:password="true"
           android:layout_width="150px"
           android:layout_height="wrap_content"
           />
       </LinearLayout>
    <LinearLayout
       android:orientation="horizontal"
       android:gravity="center_horizontal"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       >                          
       <CheckBox
           android:id="@+id/cbRemember"
           android:text="@string/cbRemember"
           android:layout_gravity="center_horizontal"
           android:checked="false"
           android:textColor="@color/character"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           />
 
       <ImageButton
           android:id="@+id/ibExit"
           android:layout_width="60px"
           android:layout_height="60px"
           android:src="@drawable/exit" />
 
       </LinearLayout>
    <LinearLayout
       android:orientation="horizontal"
       android:layout_gravity="center_horizontal"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       >                                         <!-- 声明于显示按钮的线性布局 -->
       <Button
           android:id="@+id/btnLogin"
           style="@style/button"
           android:layout_width="120px"
           android:layout_height="wrap_content"
           android:text="@string/btnLogin"
           />
       <Button
           android:id="@+id/btnReg"
           style="@style/button"
           android:layout_width="120px"
           android:layout_height="wrap_content"
           android:text="@string/btnReg"
           />
       </LinearLayout>
</LinearLayout>

 

 

 

接下来就是写对应布局的activity了,这里就只着重讲登录的实现流程了,因为相信大家对获取文本框数据和checkBox配合sharedPreference很了解了就不再赘述,当点击登录按钮的时候进入登录,登录的客户端的流程和前面讲的注册的流程是一样的,客户端把登录数据装到字符串里面,数据格式为请求头+用户名+”|”+密码,这个|是分割线。然后通过上文降到的MyConnection获取到与服务器的socket连接,然后通过这个连接的数据输出流向服务器发送数据,然后通过服务端返回的数据判断是否登录成功:

//方法:连接服务器进行登录
    public void login(){
    new Thread(){
        public void run(){
            Looper.prepare();
              try{
                  if(mc == null){
                     mc = new MyConnector(SERVER_ADDRESS, SERVER_PORT);
                  }
                  EditText etUid = (EditText)findViewById(R.id.etUid); //获得帐号EditText
                  EditText etPwd = (EditText)findViewById(R.id.etPwd); //获得密码EditText
                  String uid = etUid.getEditableText().toString().trim(); //获得输入的帐号
                  String pwd = etPwd.getEditableText().toString().trim(); //获得输入的密码
                  if(uid.equals("") || pwd.equals("")){     //判断输入是否为空
                     Toast.makeText(LoginActivity.this, "请输入帐号或密码!", Toast.LENGTH_SHORT).show();//输出提示消息
                     return;
                  }
                  String msg = "<#LOGIN#>"+uid+"|"+pwd;                //组织要返回的字符串
                  mc.dout.writeUTF(msg);                                  //发出消息
                  String receivedMsg = mc.din.readUTF();    //读取服务器发来的消息
                  pd.dismiss();
                  if(receivedMsg.startsWith("<#LOGIN_SUCCESS#>")){ //收到的消息为登录成功消息
                     receivedMsg = receivedMsg.substring(17);
                     String [] sa = receivedMsg.split("\\|");
                     CheckBox cb = (CheckBox)findViewById(R.id.cbRemember);      //获得CheckBox对象
                     if(cb.isChecked()){
                         rememberMe(uid,pwd);
                     }
                     //转到功能面板
                     Intent intent = new Intent(LoginActivity.this,FunctionTabActivity.class);
                     intent.putExtra("uno", sa[0]);
                     startActivity(intent);                    //启动功能Activity
                     finish();
                  }
                  else if(msg.startsWith("<#LOGIN_FAIL#>")){                  //收到的消息为登录失败
                     Toast.makeText(LoginActivity.this, msg.substring(14), Toast.LENGTH_LONG).show();
                     Looper.loop();
                     Looper.myLooper().quit();
                  }
              }catch(Exception e){
                  e.printStackTrace();
              }
        }
    }.start();
}
 

 

接下来我们转到服务端,看服务端执行情况,当服务器收到客户端<#LOGIN#>的请求头后,通过解析客户端发来的数据拿到用户名和密码,然后调用DBUtil.checkLogin()方法,校验用户,并返回校验结果,校验结果是ArrayList<String>的形式,其实很好理解,因为用户信息包括用户名,id,email,state等信息,我们来看看这个过程是怎么处理的:

//方法:检查用户名和密码是否正确
    public static ArrayList<String> checkLogin(String u_no,String u_pwd){
       ArrayList<String> result = new ArrayList<String>();
       Connection con = null;      //声明获取数据库连接
       PreparedStatement ps = null;                  //声明Statement对象
       ResultSet rs = null;               //声明ResultSet对象
       try{
           con = getConnection();      //获取数据库连接
           if(con == null){         //判断数据库连接对象是否
              result.add(CONNECTION_OUT);     //
              return result;
           }
           ps = con.prepareStatement("select u_no,u_name,u_email,u_state,h_id from user where u_no=? and u_pwd=?");
           ps.setString(1, u_no);             //设置预编译语句的参数
           ps.setString(2, u_pwd);            //设置预编译语句的参数
           rs = ps.executeQuery();
           if(rs.next()){              //判断结果集是否为空
              for(int i=1;i<=5;i++){
                  result.add(rs.getString(i));    //将结果集中数据存放到ArrayList中
              }
           }
           else{                    //如果数据库查无此人
              result.add(LOGIN_FAIL);  //返回登录出错信息
           }
       }catch(Exception e){
           e.printStackTrace();
       }
       finally{
           try{
              if(rs != null){
                  rs.close();
                  rs = null;
              }
           }catch(Exception e){
              e.printStackTrace();
           }
           try{
              if(ps != null){
                  ps.close();
                  ps = null;
              }
           }catch(Exception e){
              e.printStackTrace();
           }
           try{
              if(con != null){
                  con.close();
                  con = null;
              }
           }catch(Exception e){
              e.printStackTrace();
           }
       }
       return result;
    }

 

哦,原来是查询数据库,然后把数据装在一个list集合返回去,然后serverAgent把这些用户数据封装成一条格式化后的字符串,然后写给客户端:

if(msg.startsWith("<#LOGIN#>")){              //消息为登录
                  String content = msg.substring(9);        //获得消息内容
                  String [] sa = content.split("\\|");
                  ArrayList<String> result = DBUtil.checkLogin(sa[0], sa[1]);
                  if(result.size()>1){        //登录成功
                     StringBuilder sb = new StringBuilder();
                     sb.append("<#LOGIN_SUCCESS#>");
                     for(String s:result){
                         sb.append(s);
                         sb.append("|");
                     }
                     String loginInfo = sb.substring(0,sb.length()-1);
                     dout.writeUTF(loginInfo);          //返回用户的基本信息       
                  }

 

数据发给客户端了,所以我们又转回到客户端,看看客户端是怎么处理这些数据的。

客户端判断服务端发过来的数据的消息头是不是<#LOGIN_SUCCESS#>,是的话获取后的数据然后跳转到FunctionTabActivity.java,同时用intent把这些数据带过去。如果消息头是<#LOGIN_FAIL#>则给用户一个友好提示,在处理失败消息的时候我们发现用到了一个不太熟悉的东西Looper

Looper.loop();
Looper.myLooper().quit();

 

那这个Looper是个啥玩意呢,现在来科普一下:

1. Looper类用来为一个线程开启一个消息循环。 
    默认情况下android中新诞生的线程是没有开启消息循环的。(主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环。) 

    Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue 


2. 通常是通过Handler对象来与Looper进行交互的。Handler可看做是Looper的一个接口,用来向指定的Looper发送消息及定义处理方法。 

    默认情况下Handler会与其被定义时所在线程的Looper绑定,比如,Handler在主线程中定义,那么它是与主线程的Looper绑定。 

mainHandler = new Handler() 等价于new HandlerLooper.myLooper(). 

Looper.myLooper():获取当前进程的looper对象,类似的 Looper.getMainLooper() 用于获取主线程的Looper对象。 


3. 在非主线程中直接new Handler() 会报如下的错误: 

AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception 
AndroidRuntime( 6173): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
原因是非主线程中默认没有创建Looper对象,需要先调用Looper.prepare()启用Looper 

4. Looper.loop(); Looper开始工作,从消息队列里取消息,处理消息。 


    注意:写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。 


5. 基于以上知识,可实现主线程给子线程(非主线程)发送消息。

 

到现在,用户登录一个模块我们已经学习完了,需要详细请看代码。

0
0
分享到:
评论

相关推荐

    口袋微博源码

    "口袋微博源码"是一个专为社交分享设计的平台,涵盖了Web端和Android手机端的实现,这使得用户无论在电脑前还是外出时都能轻松进行微博互动。在深入探讨这个项目之前,我们先来理解一下核心的技术栈和知识点。 1. *...

    android微博应用 口袋微博

    《Android微博应用:口袋微博深度解析》 在移动互联网领域,Android平台上的应用程序开发一直备受关注,其中社交...通过深入研究口袋微博的源码,我们可以更好地掌握Android应用开发的各个环节,提升自己的技术水平。

    基于机器学习的微博情感分析微博源码+项目说明.zip

    基于机器学习的微博情感分析微博源码+项目说明.zip基于机器学习的微博情感分析微博源码+项目说明.zip基于机器学习的微博情感分析微博源码+项目说明.zip基于机器学习的微博情感分析微博源码+项目说明.zip基于机器学习...

    微博源码代码

    微博源码代码是一个用于构建简单微博系统的源代码集合,它实现了基本的微博发布、查看、评论和分享等功能。这个源码对于学习社交网络平台的开发流程、数据存储以及用户交互设计具有很高的参考价值。下面我们将深入...

    微博 源码

    【标题】:“微博源码”通常指的是某个微博应用的源代码,这可能是一个移动平台上的应用,如Android或iOS。源码是程序的基础,包含了所有编程逻辑和功能实现的细节。 【描述】:“微博源码”这个描述简洁,暗示了...

    新浪微博项目源码

    【标题】:“新浪微博项目源码”这一主题涉及的是一个基于新浪微博API实现的项目,很可能是用某种编程语言(如Java、Python或Android)编写的。这个项目可能包含了用户登录、发送微博、查看时间线、评论互动等核心...

    史上最全功能微博源码附件

    从提供的标签来看,我们可以推测这份源码可能支持与腾讯微博和新浪微博类似的平台,同时也可能适配Android移动设备。 压缩包中的文件是Java库,它们在Java开发中起着至关重要的作用: 1. `commons-httpclient-3.1....

    微博源码(asp+access)

    "微博源码(asp+access)" 提供了一个基于ASP(Active Server Pages)脚本语言和Access数据库构建的微型博客系统的源代码。这个系统可能类似于知名的微博服务,允许用户发布短消息,分享观点,与他人互动。 【描述...

    YiBo聚合微博源码.zip

    YiBo聚合微博源码是一款专为Android用户打造的聚合型微博客户端,下面是官方对本项目功能的一些介绍: 一键同步所有帐号,支持新浪、腾讯、搜狐、网易和饭否微博平台; 即拍即传,方便的拍照功能,记录生活点滴,...

    仿微博HTML源码

    综上所述,"仿微博HTML源码"是一个综合性的前端项目,涉及到HTML5、CSS3和JavaScript等多个技术领域,旨在通过静态HTML页面模拟微博的用户界面和交互体验,同时还需要考虑网页的美观性和响应式设计,以适应不同设备...

    史上最全功能微博源码

    【史上最全功能微博源码】是一份非常珍贵的IT资源,尤其对于那些热衷于社交媒体应用开发的程序员来说。这份源码提供了构建一个全面、功能丰富的微博应用的基础,包括了客户端部分,主要针对Android平台。从标签...

    Android应用源码之口袋微博 服务器 客户端代码.zip

    本篇将聚焦于"Android应用源码之口袋微博 服务器 客户端代码.zip"这一资源,通过解析其服务器和客户端代码,揭示Android应用的架构设计、网络通信以及数据存储等多个关键知识点。 首先,我们关注的是Android客户端...

    无名个人微博系统(MicroBlog)源码.zip

    无名轻博客博是一款基于PHP和Sqlite平台的简单易用的个人微博系统(MicroBlog)。致力于为您提供快速、稳定,且在使用上又极其简单、舒适的微博服务。 使用前请修改密码,默认密码:admin 配置文件:app/class/config....

    新浪微博Android客户端源码

    【标题】:“新浪微博Android客户端源码” 这是一份关于新浪微博Android客户端的源代码,它为开发者提供了一个深入理解Android应用开发,尤其是社交网络应用开发的宝贵资料。通过研究这份源码,开发者可以学习到...

    仿新浪微博源码2012726

    仿新浪微博源码 功能介绍: 使用自定义TabControl实现仿新浪微博客户端的效果,鼠标悬停时图标变成绿色 可以改变面板的大小。需要学习控件制作的可以下载学习。 实现方法: 用System.Threading.Timer加上一个简单...

    易语言源码易语言点点微博注册源码.rar

    易语言源码易语言点点微博注册源码.rar 易语言源码易语言点点微博注册源码.rar 易语言源码易语言点点微博注册源码.rar 易语言源码易语言点点微博注册源码.rar 易语言源码易语言点点微博注册源码.rar 易语言源码...

    精典源码之口袋微博服务器客户端代码.zip

    这份名为“精典源码之口袋微博服务器客户端代码”的压缩包,提供了一个宝贵的参考实例,帮助我们深入了解社交应用的架构设计和实现技术。 首先,源码参考的价值在于它能让我们窥见实际项目中的编程实践。通过阅读和...

    安卓Android源码——精典源码之口袋微博服务器客户端代码.zip

    在“口袋微博”源码中,可能会使用这两种方法之一,构建URL,设置请求方法(GET、POST),并添加请求头信息。同时,我们还需要处理异步请求,防止阻塞主线程,这通常通过AsyncTask或者Retrofit等库来实现。 2. **...

    仿新浪微博源码

    仿新浪微博的网站源码 此网站花费了8个月的时间开发的,界面UI完全用旧版微博的CSS和图片,前台用jquery,后台由Asp.net MVC3+纯ADO.Net 开发。运行的话, 数据库文件在DB_51Aspx下,附加即可(MS Sql2008),并...

    微博开发源码新浪微博

    本文将围绕“微博开发源码”这一主题,结合“新浪微博”的开发实例,深入探讨相关技术知识,旨在帮助读者理解和掌握微博平台的构建原理。 首先,我们要明确的是,“微博开发”不仅涉及前端用户界面的设计,还包括...

Global site tag (gtag.js) - Google Analytics