一口氣看完一個項目源碼(一)之用戶註冊

今天咋們看的這個項目源碼是一個微博客戶端,和服務端通信用socket寫的,項目名稱:口袋微博,和前面那個項目不一樣,這個項目略難一點,不過不要緊,讓咱們一塊兒來學習學習吧。java

         按照使用流程,首先是註冊頁面,所以咱們來寫註冊頁面,先把註冊頁面的佈局寫了:android

Xml代碼  
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout  
  3.        xmlns:android="http://schemas.android.com/apk/res/android"  
  4.        android:orientation="vertical"  
  5.        android:gravity="center_horizontal"  
  6.        android:background="@drawable/back"  
  7.        android:paddingTop="25px"  
  8.        android:layout_width="fill_parent"  
  9.        android:layout_height="fill_parent"  
  10.        >                                                                                          <!-- 聲明一個線性佈局 -->  
  11.        <LinearLayout  
  12.               android:orientation="horizontal"  
  13.               android:layout_width="wrap_content"  
  14.               android:layout_height="wrap_content"       
  15.               >                                                                                   <!-- 聲明一個顯示暱稱的線性佈局 -->  
  16.               <TextView  
  17.                      android:text="@string/tvName"  
  18.                      android:layout_width="100px"  
  19.                      style="@style/text"  
  20.                      android:layout_height="wrap_content"  
  21.                      android:layout_gravity="center_vertical"  
  22.                      />  
  23.               <EditText  
  24.                      android:id="@+id/etName"  
  25.                      android:singleLine="true"  
  26.                      android:layout_width="160px"  
  27.                      android:layout_height="wrap_content"  
  28.                      />  
  29.               </LinearLayout>  
  30.        <LinearLayout  
  31.               android:orientation="horizontal"  
  32.               android:layout_width="wrap_content"  
  33.               android:layout_height="wrap_content"  
  34.               >                                                                                   <!-- 聲明顯示密碼的線性佈局 -->  
  35.               <TextView  
  36.                      android:text="@string/tvPwd"  
  37.                      style="@style/text"  
  38.                      android:layout_width="100px"  
  39.                      android:layout_height="wrap_content"  
  40.                      android:layout_gravity="center_vertical"  
  41.                      />  
  42.               <EditText  
  43.                      android:id="@+id/etPwd1"  
  44.                      android:singleLine="true"  
  45.                      android:password="true"  
  46.                      android:layout_width="160px"  
  47.                      android:layout_height="wrap_content"  
  48.                      />  
  49.               </LinearLayout>  
  50.        <LinearLayout  
  51.               android:orientation="horizontal"  
  52.               android:layout_width="wrap_content"  
  53.               android:layout_height="wrap_content"  
  54.               >                                                                            <!-- 聲明顯示確認密碼的線性佈局 -->  
  55.               <TextView  
  56.                      android:text="@string/tvPwd2"  
  57.                      style="@style/text"  
  58.                      android:layout_width="100px"  
  59.                      android:layout_height="wrap_content"  
  60.                      android:layout_gravity="center_vertical"  
  61.                      />                                                                    <!-- 聲明TextView控件 -->  
  62.               <EditText  
  63.                      android:id="@+id/etPwd2"  
  64.                      android:singleLine="true"  
  65.                      android:password="true"  
  66.                      android:layout_width="160px"  
  67.                      android:layout_height="wrap_content"  
  68.                      />                                                                    <!-- 聲明輸入確認密碼EditText控件 -->  
  69.               </LinearLayout>  
  70.        <LinearLayout  
  71.               android:orientation="horizontal"  
  72.               android:layout_width="wrap_content"  
  73.               android:layout_height="wrap_content"  
  74.               >                                                                            <!-- 聲明包含Email輸入的線性佈局 -->  
  75.               <TextView  
  76.                      android:text="@string/tvEmail"  
  77.                      style="@style/text"  
  78.                      android:layout_width="100px"  
  79.                      android:layout_height="wrap_content"  
  80.                      android:layout_gravity="center_vertical"  
  81.                      />  
  82.               <EditText  
  83.                      android:id="@+id/etEmail"  
  84.                      android:singleLine="true"  
  85.                      android:layout_width="160px"  
  86.                      android:layout_height="wrap_content"  
  87.                      />  
  88.               </LinearLayout>  
  89.        <LinearLayout  
  90.               android:orientation="horizontal"  
  91.               android:layout_width="wrap_content"  
  92.               android:layout_height="wrap_content"  
  93.               >                                                                            <!-- 聲明包含心情輸入的線性佈局 -->  
  94.               <TextView  
  95.                      android:text="@string/tvStatus"  
  96.                      style="@style/text"  
  97.                      android:layout_width="100px"  
  98.                      android:layout_height="wrap_content"  
  99.                      android:layout_gravity="center_vertical"  
  100.                      />  
  101.               <EditText  
  102.                      android:id="@+id/etStatus"  
  103.                      android:singleLine="true"  
  104.                      android:text="@string/etStatus"  
  105.                      android:layout_width="160px"  
  106.                      android:layout_height="wrap_content"  
  107.                      />  
  108.               </LinearLayout>  
  109.        <LinearLayout  
  110.               android:orientation="horizontal"  
  111.               android:layout_width="wrap_content"  
  112.               android:layout_height="wrap_content"  
  113.               >  
  114.               <Button  
  115.                      android:id="@+id/btnReg"  
  116.                      style="@style/button"  
  117.                      android:layout_width="120px"  
  118.                      android:layout_height="wrap_content"  
  119.                      android:text="@string/btnReg"  
  120.                      />  
  121.               <Button  
  122.                      android:id="@+id/btnBack"  
  123.                      style="@style/button"  
  124.                      android:layout_width="120px"  
  125.                      android:layout_height="wrap_content"  
  126.                      android:text="@string/btnBack"  
  127.                      />  
  128.               </LinearLayout>  
  129.        <LinearLayout  
  130.               android:orientation="vertical"  
  131.               android:visibility="visible"  
  132.               android:id="@+id/regResult"  
  133.               android:layout_width="wrap_content"  
  134.               android:layout_height="wrap_content"  
  135.               >  
  136.               <LinearLayout  
  137.                      android:orientation="horizontal"  
  138.                      android:layout_width="wrap_content"  
  139.                      android:layout_height="wrap_content"  
  140.                      >  
  141.                      <TextView  
  142.                             android:text="@string/regSuccess"  
  143.                             style="@style/text"  
  144.                             android:layout_width="wrap_content"  
  145.                             android:layout_height="wrap_content"  
  146.                             />  
  147.                      <EditText  
  148.                             android:id="@+id/etUno"  
  149.                             android:layout_width="wrap_content"  
  150.                             android:layout_height="wrap_content"  
  151.                             android:cursorVisible="false"  
  152.                             />  
  153.                      </LinearLayout>  
  154.               <Button  
  155.                      android:id="@+id/btnEnter"  
  156.                      style="@style/text"  
  157.                      android:layout_gravity="right"  
  158.                      android:text="@string/btnEnter"  
  159.                      android:layout_width="wrap_content"  
  160.                      android:layout_height="wrap_content"  
  161.                      />  
  162.               </LinearLayout>  
  163. </LinearLayout>  

 

佈局寫好之後,咱們須要給這些佈局添加點擊事件(主要是註冊),經過自定義一個MyConnection指定地址和端口號鏈接socket獲得DataOutputStream和一個DataInputStream,把要發送的註冊信息封裝好(這裏封裝用的是消息頭+分隔符的形式)把消息發給服務端,而後經過DataInputStream讀取服務端返回的結果,若是服務端返回結果的請求頭爲<#REG_SUCCESS#>表明註冊成功,同時用一個變量記住返回的結果,不然就是註冊失敗。數據庫

註冊代碼以下:服務器

Java代碼  
  1. /** 
  2.      * 方法:鏈接服務器,進行註冊 
  3.      */  
  4.     public void register(){  
  5.        new Thread(){  
  6.            public void run(){  
  7.               Looper.prepare();  
  8.               //1.得到用戶輸入的數據並進行驗證  
  9.               EditText etName = (EditText)findViewById(R.id.etName);         //得到暱稱EditText對象  
  10.               EditText etPwd1 = (EditText)findViewById(R.id.etPwd1);         //得到密碼EditText對象  
  11.               EditText etPwd2 = (EditText)findViewById(R.id.etPwd2);         //得到確認密碼EditText對象  
  12.               EditText etEmail = (EditText)findViewById(R.id.etEmail);       //得到郵箱EditText對象  
  13.               EditText etStatus = (EditText)findViewById(R.id.etStatus);     //得到心情EditText對象  
  14.               String name = etName.getEditableText().toString().trim();      //得到暱稱  
  15.               String pwd1 = etPwd1.getEditableText().toString().trim();      //得到密碼  
  16.               String pwd2 = etPwd2.getEditableText().toString().trim();      //得到確認密碼  
  17.               String email = etEmail.getEditableText().toString().trim();    //得到郵箱  
  18.               String status = etStatus.getEditableText().toString().trim();  //得到狀態  
  19.               if(name.equals("") || pwd1.equals("") || pwd2.equals("") || email.equals("") || status.equals("")){  
  20.                   Toast.makeText(RegActivity.this, "請將註冊信息填寫完整", Toast.LENGTH_LONG).show();  
  21.                   return;  
  22.               }  
  23.               if(!pwd1.equals(pwd2)){            //判斷兩次輸入的密碼是否一致  
  24.                   Toast.makeText(RegActivity.this, "兩次輸入的密碼不一致!", Toast.LENGTH_LONG).show();  
  25.                   return;  
  26.               }  
  27.               //2.鏈接服務器開始傳數據  
  28.               try{  
  29.                   mc = new MyConnector(SERVER_ADDRESS, SERVER_PORT);  
  30.                   String regInfo = "<#REGISTER#>"+name+"|"+pwd1+"|"+email+"|"+status;  
  31.                   mc.dout.writeUTF(regInfo);  
  32.                   String result = mc.din.readUTF();  
  33.                   pd.dismiss();  
  34.                   if(result.startsWith("<#REG_SUCCESS#>")){     //返回信息爲註冊成功  
  35.                      result= result.substring(15);      //去掉信息頭  
  36.                      uno = result;            //記錄用戶的ID  
  37.                      myHandler.sendEmptyMessage(0);            //發出Handler消息  
  38.                      Toast.makeText(RegActivity.this, "註冊成功!", Toast.LENGTH_LONG).show();  
  39.                   }  
  40.                   else{      //註冊失敗  
  41.                      Toast.makeText(RegActivity.this, "註冊失敗!請重試!", Toast.LENGTH_LONG).show();  
  42.                   }  
  43.               }  
  44.               catch(Exception e){  
  45.                   e.printStackTrace();  
  46.               }  
  47.            }  
  48.        }.start();  
  49.     }  

 接下來咱們來寫服務端的代碼,由於服務端用的socket,所以須要一個入口函數,這個入口在Server.java文件中,經過它開啓一個服務線程:socket

Java代碼  
  1. public class Server{  
  2.     public static void main(String args[]){  
  3.         try{  
  4.             ServerSocket ss = new ServerSocket(8888);  
  5.             ServerThread st = new ServerThread(ss);  
  6.             st.start();  
  7.             System.out.println("Listening...");  
  8.         }catch(Exception e){  
  9.             e.printStackTrace();  
  10.         }  
  11.     }  
  12. }  

 咱們轉到這個線程類裏面,發現實現是經過調用serverSocket的accept()方法,監聽客戶端請求。對於請求過來的數據,專門寫一個代理類ServerAgent.java來處理。ide

Java代碼  
  1. package wpf;  
  2.   
  3. import java.net.ServerSocket;  
  4. import java.net.Socket;  
  5. import java.net.SocketException;  
  6.   
  7. public class ServerThread extends Thread{  
  8.     public ServerSocket ss;     //聲明ServerSocket對象  
  9.     public boolean flag = false;  
  10.       
  11.     public ServerThread(ServerSocket ss){   //構造器  
  12.         this.ss = ss;     
  13.         flag = true;  
  14.     }  
  15.     public void run(){  
  16.         while(flag){  
  17.             try{  
  18.                 Socket socket = ss.accept();  
  19.                 ServerAgent sa = new ServerAgent(socket);  
  20.                 sa.start();  
  21.             }  
  22.             catch(SocketException se){  
  23.                 try{  
  24.                     ss.close();  
  25.                     ss = null;  
  26.                     System.out.println("ServerSocket closed");  
  27.                 }catch(Exception ee){  
  28.                     ee.printStackTrace();  
  29.                 }  
  30.             }  
  31.             catch(Exception e){  
  32.                 e.printStackTrace();  
  33.             }  
  34.         }  
  35.     }  
  36. }  

 咱們來看ServerAgent是怎麼實現的。函數

代理線程經過構造函數拿到數據輸入和輸出流,而後在run方法裏面處理用戶請求。接下來就是對請求頭的判斷,咱們這裏先只講註冊請求,收到的是註冊請求,解析用戶發過來的數據,而後經過寫一個數據庫工具類DBUtil類處理用戶發送過來的數據。並將處理結果返回給客戶端,而後客戶端經過判斷從服務器獲取的請求結果更新ui界面。兩個主要的方法:工具

Java代碼  
  1. public ServerAgent(Socket socket){  
  2.        this.socket = socket;  
  3.        try {  
  4.            this.din = new DataInputStream(socket.getInputStream());  
  5.            this.dout = new DataOutputStream(socket.getOutputStream());  
  6.            flag =true;  
  7.        } catch (IOException e) {  
  8.            e.printStackTrace();  
  9.        }  
  10.     }  
  11.    
  12. public void run(){  
  13.        while(flag){  
  14.            try {  
  15.               String msg = din.readUTF();        //接收客戶端發來的消息  
  16. //            System.out.println("收到的消息是:"+msg);  
  17. if(msg.startsWith("<#REGISTER#>")){           //消息爲用戶註冊  
  18.                   msg = msg.substring(12); //得到字符串值  
  19.                   String [] sa = msg.split("\\|");   //切割字符串  
  20.                   String regResult = DBUtil.registerUser(sa[0], sa[1], sa[2], sa[3], "1");  
  21.                   if(regResult.equals(REGISTER_FAIL)){      //註冊失敗  
  22.                      dout.writeUTF("<#REG_FAIL#>");  
  23.                   }  
  24.                   else{  
  25.                      dout.writeUTF("<#REG_SUCCESS#>"+regResult);  
  26.                   }  
  27.               }  
  28. }  

 

因而,咱們轉到DbUtil類裏面,看書怎麼保存到數據庫中的。咱們發現存儲使用通常存儲方式,只是裏面有設置存儲編碼方式,還用到了prepareStatement。處理結束返回處理結果,若是鏈接爲null返回鏈接失敗,若是保存到數據庫成功就返回註冊完的用戶id,不然返回註冊失敗。完了以後不要忘了釋放資源。oop

//方法:註冊用戶佈局

   

Java代碼  
  1. public static String registerUser(String u_name,String u_pwd,String u_email,String u_state,String h_id){  
  2.       String result=null;  
  3.       Connection con = null;      //聲明數據庫鏈接對象  
  4.       PreparedStatement ps = null;       //聲明語句對象  
  5.       try{  
  6.           con = getConnection();  
  7.           if(con == null){         //判斷是否成功獲取鏈接  
  8.              result = CONNECTION_OUT;  
  9.              return result;       //返回方法的執行  
  10.           }  
  11.           ps = con.prepareStatement("insert into user(u_no,u_name,u_pwd,u_email,u_state,h_id)" +  
  12.                  "values(?,?,?,?,?,?)");     //構建SQL語句  
  13.           String u_no = String.valueOf(getMax(USER));   //得到分配給用戶的賬號  
  14.           u_name = new String(u_name.getBytes(),"ISO-8859-1");    //轉成ISO-8859-1以插入數據庫  
  15.           u_state = new String(u_state.getBytes(),"ISO-8859-1");      //轉成ISO-8859-1以插入數據庫  
  16.           int no = Integer.valueOf(u_no);  
  17.           int hid = Integer.valueOf(h_id);  
  18.           ps.setInt(1, no);        //設置PreparedStatement的參數  
  19.           ps.setString(2, u_name);  
  20.           ps.setString(3, u_pwd);  
  21.           ps.setString(4, u_email);  
  22.           ps.setString(5, u_state);  
  23.           ps.setInt(6,hid);  
  24.           int count = ps.executeUpdate();        //執行插入  
  25.           if(count == 1){      //若是插入成功  
  26.              result = u_no;       //得到玩家的賬號  
  27.           }  
  28.           else{                    //若是沒有插入數據  
  29.              result = REGISTER_FAIL;     //得到出錯信息  
  30.           }  
  31.       }catch(Exception e){  
  32.           e.printStackTrace();  
  33.       }  
  34.       finally{  
  35.           try{  
  36.              if(ps != null){  
  37.                  ps.close();  
  38.                  ps = null;  
  39.              }  
  40.           }catch(Exception e){  
  41.              e.printStackTrace();  
  42.           }  
  43.           try{  
  44.              if(con != null){  
  45.                  con.close();  
  46.                  con = null;  
  47.              }  
  48.           }catch(Exception e){  
  49.              e.printStackTrace();  
  50.           }  
  51.       }  
  52.       return result;  
  53.    }  

 接下來即是客戶端處理服務端返回數據:

客戶端處理完服務端發過來的數據,就經過handler更新界面,讓進入我的中心這個按鈕可見,同時拿到用戶id轉到我的中心頁面。這樣,一個用戶註冊的模塊寫好了。

Java代碼  
  1. Handler myHandler = new Handler(){  
  2.        @Override  
  3.        public void handleMessage(Message msg) {  
  4.            switch(msg.what){  
  5.            case 0:        
  6.               View linearLayout = (LinearLayout)findViewById(R.id.regResult);    //得到線性佈局  
  7.               linearLayout.setVisibility(View.VISIBLE);     //設置可見性  
  8.               EditText etUno = (EditText)findViewById(R.id.etUno);  
  9.               etUno.setText(uno);       
  10.               break;  
  11.            }  
  12.            super.handleMessage(msg);  
  13.        }  
  14.     };  

 下一篇介紹用戶登陸時如何實現的。

相關文章
相關標籤/搜索