Android 配置型 onClick 事件

XML 代码

今天咋们看的这个项目源码是一个微博客户端,和服务端通讯用socket写的,项目名称:口袋微博,和前面那个项目不同,这个项目略难一点,不过没关系,让我们一起来学习学习吧。

做安卓开发有很多时候都是要和web交互的,我们很难制作本地应用,这次把小弟整出来的安卓和服务器通讯贡献出来,希望能帮到需要的朋友,同时也是加深印象。

<Button android:text=”gotoHehe” android:layout_width=”wrap_content”
android:layout_height=”wrap_content” android:id=”@+id/gotoHehe”
android:layout_weight=”1″ android:onClick=”gotoHehe” />

         按照使用流程,首先是注册页面,因此我们来写注册页面,先把注册页面的布局写了:

我们先来搭建安卓客户端,首先写好布局文件:

java 代码

Xml代码  

 

public void gotoHehe(View view) { }

  1. <?xml version=”1.0″ encoding=”utf-8″?>  
  2. <LinearLayout  
  3.        xmlns: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>  

1.布局文件Register.xml:

java 代码中,类保护级别应该是 public(.NET 的话 protected 即可)。

 

 

这个代码必须写在 Activity 中,如果写在 Fragment 中是无效的。

布局写好以后,我们需要给这些布局添加点击事件(主要是注册),通过自定义一个MyConnection指定地址和端口号连接socket得到DataOutputStream和一个DataInputStream,把要发送的注册信息封装好(这里封装用的是消息头+分隔符的形式)把消息发给服务端,然后通过DataInputStream读取服务端返回的结果,如果服务端返回结果的请求头为<#REG_SUCCESS#>代表注册成功,同时用一个变量记住返回的结果,否则就是注册失败。

Xml代码 

注册代码如下:

 

Java代码  

  1. <?xml version=”1.0″ encoding=”utf-8″?>  
  2. <LinearLayout xmlns:android=””  
  3.     android:layout_width=”fill_parent”  
  4.     android:layout_height=”fill_parent”  
  5.     android:background=”@drawable/fuction_fond_bg”  
  6.     android:orientation=”vertical” >  
  7.   
  8.     <ImageView  
  9.         android:layout_width=”fill_parent”  
  10.         android:layout_height=”wrap_content”  
  11.         android:src=”@drawable/setting_btn” >  
  12.     </ImageView>  
  13.   
  14.     <ScrollView  
  15.         android:layout_width=”wrap_content”  
  16.         android:layout_height=”wrap_content” >  
  17.   
  18.         <LinearLayout  
  19.             android:layout_width=”fill_parent”  
  20.             android:layout_height=”wrap_content”  
  21.             android:layout_gravity=”center_horizontal”  
  22.             android:orientation=”vertical” >  
  23.   
  24.             <TextView  
  25.                 android:layout_width=”fill_parent”  
  26.                 android:layout_height=”wrap_content”  
  27.                 android:text=”请输入您的注册信息:”  
  28.                 android:textColor=”#6495ED”  
  29.                 android:textSize=”20dip” >  
  30.             </TextView>  
  31.   
  32.             <View  
  33.                 android:layout_width=”fill_parent”  
  34.                 android:layout_height=”2dip”  
  35.                 android:background=”#FF909090″ />  
  36.   
  37.             <LinearLayout  
  38.                 android:layout_width=”fill_parent”  
  39.                 android:layout_height=”wrap_content”  
  40.                 android:layout_margin=”20dip”  
  41.                 android:background=”#FFFFFF”  
  42.                 android:orientation=”vertical”  
  43.                 android:padding=”10dp” >  
  44.   
  45.                 <LinearLayout  
  46.                     android:layout_width=”wrap_content”  
  47.                     android:layout_height=”wrap_content”  
  48.                     android:orientation=”horizontal” >  
  49.   
  50.                     <TextView  
  51.                         android:layout_width=”wrap_content”  
  52.                         android:layout_height=”wrap_content”  
  53.                         android:text=”帐   号:  ”  
  54.                         android:textColor=”#6495ED” >  
  55.                     </TextView>  
  56.   
  57.                     <EditText  
  58.                         android:id=”@+id/username”  
  59.                         android:layout_width=”190dip”  
  60.                         android:layout_height=”wrap_content” >  
  61.                     </EditText>  
  62.                 </LinearLayout>  
  63.   
  64.                 <View  
  65.                     android:layout_width=”fill_parent”  
  66.                     android:layout_height=”2dip”  
  67.                     android:background=”#FF909090″ />  
  68.   
  69.                 <LinearLayout  
  70.                     android:layout_width=”wrap_content”  
  71.                     android:layout_height=”wrap_content”  
  72.                     android:orientation=”horizontal” >  
  73.   
  74.                     <TextView  
  75.                         android:layout_width=”wrap_content”  
  76.                         android:layout_height=”wrap_content”  
  77.                         android:text=”密   码:  ”  
  78.                         android:textColor=”#6495ED” >  
  79.                     </TextView>  
  80.   
  81.                     <EditText  
  82.                         android:id=”@+id/password”  
  83.                         android:layout_width=”190dip”  
  84.                         android:layout_height=”wrap_content”  
  85.                         android:password=”true” >  
  86.                     </EditText>  
  87.                 </LinearLayout>  
  88.   
  89.                 <View  
  90.                     android:layout_width=”fill_parent”  
  91.                     android:layout_height=”2dip”  
  92.                     android:background=”#FF909090″ />  
  93.   
  94.                 <LinearLayout  
  95.                     android:layout_width=”wrap_content”  
  96.                     android:layout_height=”wrap_content”  
  97.                     android:orientation=”horizontal” >  
  98.   
  99.                     <TextView  
  100.                         android:layout_width=”wrap_content”  
  101.                         android:layout_height=”wrap_content”  
  102.                         android:text=”确认密码 :  ”  
  103.                         android:textColor=”#6495ED” >  
  104.                     </TextView>  
  105.   
  106.                     <EditText  
  107.                         android:id=”@+id/confirmpsw”  
  108.                         android:layout_width=”190dip”  
  109.                         android:layout_height=”wrap_content”  
  110.                         android:password=”true” >  
  111.                     </EditText>  
  112.                 </LinearLayout>  
  113.   
  114.                 <View  
  115.                     android:layout_width=”fill_parent”  
  116.                     android:layout_height=”2dip”  
  117.                     android:background=”#FF909090″ />  
  118.   
  119.                 <LinearLayout  
  120.                     android:layout_width=”wrap_content”  
  121.                     android:layout_height=”wrap_content”  
  122.                     android:orientation=”horizontal” >  
  123.   
  124.                     <TextView  
  125.                         android:layout_width=”wrap_content”  
  126.                         android:layout_height=”wrap_content”  
  127.                         android:text=”昵   称:  ”  
  128.                         android:textColor=”#6495ED” >  
  129.                     </TextView>  
  130.   
  131.                     <EditText  
  132.                         android:id=”@+id/nikename”  
  133.                         android:layout_width=”190dip”  
  134.                         android:layout_height=”wrap_content” >  
  135.                     </EditText>  
  136.                 </LinearLayout>  
  137.   
  138.                 <View  
  139.                     android:layout_width=”fill_parent”  
  140.                     android:layout_height=”2dip”  
  141.                     android:background=”#FF909090″ />  
  142.   
  143.                 <LinearLayout  
  144.                     android:layout_width=”wrap_content”  
  145.                     android:layout_height=”wrap_content”  
  146.                     android:orientation=”horizontal” >  
  147.   
  148.                     <TextView  
  149.                         android:layout_width=”wrap_content”  
  150.                         android:layout_height=”wrap_content”  
  151.                         android:layout_marginTop=”5dp”  
  152.                         android:text=”性   别:  ”  
  153.                         android:textColor=”#6495ED” >  
  154.                     </TextView>  
  155.   
  156.                     <RadioGroup  
  157.                         android:id=”@+id/gender_group_rb”  
  158.                         android:layout_width=”fill_parent”  
  159.                         android:layout_height=”wrap_content”  
  160.                         android:orientation=”horizontal” >  
  161.   
  162.                         <RadioButton  
  163.                             android:id=”@+id/male_rb”  
  164.                             android:layout_width=”wrap_content”  
  165.                             android:layout_height=”wrap_content”  
  166.                             android:text=”男 ”  
  167.                             android:textColor=”#6495ED” >  
  168.                         </RadioButton>  
  169.   
  170.                         <RadioButton  
  171.                             android:id=”@+id/female_rb”  
  172.                             android:layout_width=”wrap_content”  
  173.                             android:layout_height=”wrap_content”  
  174.                             android:text=”女”  
  175.                             android:textColor=”#6495ED” >  
  176.                         </RadioButton>  
  177.                     </RadioGroup>  
  178.                 </LinearLayout>  
  179.   
  180.                 <LinearLayout  
  181.                     android:layout_width=”wrap_content”  
  182.                     android:layout_height=”wrap_content”  
  183.                     android:orientation=”horizontal” >  
  184.   
  185.                     <ImageView  
  186.                         android:layout_width=”fill_parent”  
  187.                         android:layout_height=”wrap_content” >  
  188.                     </ImageView>  
  189.                 </LinearLayout>  
  190.   
  191.                 <View  
  192.                     android:layout_width=”fill_parent”  
  193.                     android:layout_height=”2dip”  
  194.                     android:background=”#FF909090″ />  
  195.   
  196.                 <Button  
  197.                     android:id=”@+id/register_btn”  
  198.                     android:layout_width=”fill_parent”  
  199.                     android:layout_height=”40dp”  
  200.                     android:layout_margin=”10dp”  
  201.                     android:background=”@drawable/new_button_bg”  
  202.                     android:gravity=”center”  
  203.                     android:text=”注 册” />  
  204.             </LinearLayout>  
  205.         </LinearLayout>  
  206.     </ScrollView>  
  207.   
  208. </LinearLayout>  
  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.     }  

 2.Activity文件:RegisterActivity.java

 接下来我们来写服务端的代码,因为服务端用的socket,因此需要一个入口函数,这个入口在Server.java文件中,通过它开启一个服务线程:

 

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. }  

1.初始化视图控件:

 我们转到这个线程类里面,发现实现是通过调用serverSocket的accept()方法,监听客户端请求。对于请求过来的数据,专门写一个代理类ServerAgent.java来处理。

 

Java代码  

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是怎么实现的。

  1. /** 
  2.      * 初始化视图控件 
  3.      */  
  4.     private void initView() {  
  5.         username_et = (EditText) findViewById(R.id.username);  
  6.         password_et = (EditText) findViewById(R.id.password);  
  7.         confirmpsw_et = (EditText) findViewById(R.id.confirmpsw);  
  8.         nikename_et = (EditText) findViewById(R.id.nikename);  
  9.         register_btn = (Button) findViewById(R.id.register_btn);  
  10.         register_btn.setOnClickListener(listener);  
  11.         gender_group_rb = (RadioGroup) findViewById(R.id.gender_group_rb);  
  12.         gender_group_rb.setOnCheckedChangeListener(checkListener);  
  13.     }  

代理线程通过构造函数拿到数据输入和输出流,然后在run方法里面处理用户请求。接下来就是对请求头的判断,我们这里先只讲注册请求,收到的是注册请求,解析用户发过来的数据,然后通过写一个数据库工具类DBUtil类处理用户发送过来的数据。并将处理结果返回给客户端,然后客户端通过判断从服务器获取的请求结果更新ui界面。两个主要的方法:

 2.当我们填写好数据后,点击注册按钮,调用注册这个方法:

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. }  

 

 

Java代码 

于是,我们转到DbUtil类里面,看书怎么保存到数据库中的。我们发现存储使用一般存储方式,只是里面有设置存储编码方式,还用到了prepareStatement。处理结束返回处理结果,如果连接为null返回连接失败,如果保存到数据库成功就返回注册完的用户id,否则返回注册失败。完了之后不要忘了释放资源。

 

//方法:注册用户

  1. /** 
  2.      * 注册按钮的点击 
  3.      */  
  4.     private OnClickListener listener = new OnClickListener() {  
  5.         @Override  
  6.         public void onClick(View v) {  
  7.             doRegister();  
  8.         }  
  9.     };  
  10.   
  11.     /** 
  12.      * 开始注册 
  13.      */  
  14.     private void doRegister() {  
  15.         pd = ProgressDialog.show(RegisterActivity.this, “正在注册..”,  
  16.                 “正在注册中..请稍后….”, true, true);  
  17.         // 1.获取数据  
  18.         username = username_et.getText().toString();  
  19.         password = password_et.getText().toString();  
  20.         confirmpsw = confirmpsw_et.getText().toString();  
  21.         nickname = nikename_et.getText().toString();  
  22.         // 2.进行校验,不对返回,否则继续  
  23.         if (checkNull(username) || checkNull(password) || checkNull(confirmpsw)  
  24.                 || checkNull(gender) || checkNull(nickname)) {  
  25.             Toast.makeText(this, “请填写完整数据”, Toast.LENGTH_SHORT).show();  
  26.             // TODO 这里本应该完整校验的,暂时偷懒  
  27.             return;  
  28.         }  
  29.         // 3.开始向服务器注册  
  30.         Thread thread = new Thread(registerRunnable);  
  31.         thread.start();  
  32.   
  33.     }  

   

 因为做的比较简陋,详细的表单校验没有写,点击注册开启一个子线程来处理和服务器打交道的耗时操作。在注册的过程中用的httpUrlConnection连接服务器,向服务器提交注册信息。

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.    }  

 

 接下来便是客户端处理服务端返回数据:

Java代码 

客户端处理完服务端发过来的数据,就通过handler更新界面,让进入个人中心这个按钮可见,同时拿到用户id转到个人中心页面。这样,一个用户注册的模块写好了。

 

Java代码  

  1. /** 
  2.      * 开始注册的线程 
  3.      */  
  4.     Runnable registerRunnable = new Runnable() {  
  5.         @Override  
  6.         public void run() {  
  7.             // 1.拼装数据  
  8.             StringBuilder sb = new StringBuilder();  
  9.             sb.append(“<users>”);  
  10.             sb.append(“<user>”);  
  11.             sb.append(“<username>”);  
  12.             sb.append(username);  
  13.             sb.append(“</username>”);  
  14.               
  15.             sb.append(“<password>”);  
  16.             sb.append(password);  
  17.             sb.append(“</password>”);  
  18.   
  19.             sb.append(“<nickname>”);  
  20.             sb.append(nickname);  
  21.             sb.append(“</nickname>”);  
  22.   
  23.             sb.append(“<gender>”);  
  24.             sb.append(gender);  
  25.             sb.append(“</gender>”);  
  26.               
  27.             sb.append(“</user>”);  
  28.             sb.append(“</users>”);  
  29.             // 2.开始写数据  
  30.             byte content[] = sb.toString().getBytes();  
  31.             try {  
  32.                 URL url = new URL(Constant.REGISTER_SERVLET);  
  33.                 HttpURLConnection conn = (HttpURLConnection) url  
  34.                         .openConnection();  
  35.                 conn.setDoInput(true);  
  36.                 conn.setDoOutput(true);  
  37.                 conn.setRequestMethod(“POST”);  
  38.                 conn.setRequestProperty(“Content-Type”, “mutipart/form-data”);  
  39.                 conn.setRequestProperty(“Content-Length”, content.length + “”);  
  40.                 conn.getOutputStream().write(content);  
  41.                 // 3.获取服务器返回的数据  
  42.                 if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {  
  43.                     InputStream in = conn.getInputStream();  
  44.   
  45.                     RegisterResultTool resultTool = new RegisterResultTool();  
  46.                     String result = resultTool.getResultFromInputStream(in);  
  47.                     // 4.提交结果  
  48.                     Message msg = new Message();  
  49.                     msg.obj = result;  
  50.                     msg.what = 200;  
  51.                     registerResultHandler.sendMessage(msg);  
  52.   
  53.                 }  
  54.             } catch (IOException e) {  
  55.                 Message msg = new Message();  
  56.                 msg.what = 400;  
  57.                 registerResultHandler.sendMessage(msg);  
  58.                 e.printStackTrace();  
  59.             }  
  60.   
  61.             pd.cancel();  
  62.         }  
  63.     };  
  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.     };  

 向服务器提交数据后,服务器会返回一些结果数据,我们就需要处理这些结果数据:

 下一篇介绍用户登录时如何实现的。

 

 

Java代码 

 

  1. /** 
  2.      * 处理服务器返回结果的类 
  3.      *  
  4.      * @author Larson 
  5.      *  
  6.      */  
  7.     private class RegisterResultTool {  
  8.         /** 
  9.          * 从服务器返回的数据中读取返回结果 
  10.          *  
  11.          * @param in 
  12.          * @return 
  13.          */  
  14.         public String getResultFromInputStream(InputStream in) {  
  15.             String result = “”;  
  16.             SAXParserFactory sf = SAXParserFactory.newInstance();  
  17.   
  18.             try {  
  19.                 XMLReader xr = sf.newSAXParser().getXMLReader();  
  20.   
  21.                 RegisterResultHandler rrh = new RegisterResultHandler();  
  22.                 xr.setContentHandler(rrh);  
  23.                 xr.parse(new InputSource(in));  
  24.                 result = rrh.getResult();  
  25.   
  26.             } catch (Exception e) {  
  27.                 e.printStackTrace();  
  28.             }  
  29.             return result;  
  30.         }  
  31.   
  32.     }  
  33.   
  34.     /** 
  35.      * 因为服务器返回的是xml形式,所以需要解析 
  36.      *  
  37.      * @author Larson 
  38.      *  
  39.      */  
  40.     private class RegisterResultHandler extends DefaultHandler {  
  41.         /** 
  42.          * 获得的服务器返回结果 
  43.          */  
  44.         private String result;  
  45.         /** 
  46.          * 临时存取数据的变量 
  47.          */  
  48.         private String var=””;  
  49.   
  50.         /** 
  51.          * 获取返回值 
  52.          *  
  53.          * @return 
  54.          */  
  55.         public String getResult() {  
  56.             return result;  
  57.         }  
  58.   
  59.         @Override  
  60.         public void startElement(String uri, String localName, String qName,  
  61.                 Attributes attributes) throws SAXException {  
  62.             super.startElement(uri, localName, qName, attributes);  
  63.         }  
  64.   
  65.         @Override  
  66.         public void characters(char[] ch, int start, int length)  
  67.                 throws SAXException {  
  68.             var += new String(ch, start, length);  
  69.             super.characters(ch, start, length);  
  70.         }  
  71.   
  72.         @Override  
  73.         public void endElement(String uri, String localName, String qName)  
  74.                 throws SAXException {  
  75.             /** 
  76.              * 取出info标签的数据(服务器返回的注册结果) 
  77.              */  
  78.             if (qName.equals(“info”)) {  
  79.                 result = var.trim();  
  80.             }  
  81.             super.endElement(uri, localName, qName);  
  82.         }  
  83.     }  

 获取结果后,在handler中刷新ui通知用户:

 

 

Java代码 

 

  1. /** 
  2.  * 处理返回结果的handler 
  3.  * 如果返回的数据是服务器给的成功数据,注册成功,否则就是服务器有问题 
  4.  */  
  5. private Handler registerResultHandler = new Handler() {  
  6.     public void handleMessage(Message msg) {  
  7.         System.out.println(msg.obj+”————-“+msg.what);  
  8.         switch (msg.what) {  
  9.         case 400:  
  10.             Toast.makeText(RegisterActivity.this, “注册失败.”, Toast.LENGTH_SHORT).show();  
  11.             break;  
  12.         case 200:  
  13.             String str = (String) msg.obj;  
  14.             if(str.contains(“regist_ok”))  
  15.                 Toast.makeText(RegisterActivity.this, “注册成功.”, Toast.LENGTH_SHORT).show();  
  16.             else  
  17.                 Toast.makeText(RegisterActivity.this, “服务器未开放.”, Toast.LENGTH_SHORT).show();  
  18.             break;  
  19.         default:  
  20.             break;  
  21.         }  
  22.     };  
  23. };  

 接下来我们来写服务器端:

 

服务器段用registerServlet处理客户端请求:registerServlet.java:

 

Java代码 

 

  1. package com.larson.pm;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.io.PrintWriter;  
  6.   
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.http.HttpServlet;  
  9. import javax.servlet.http.HttpServletRequest;  
  10. import javax.servlet.http.HttpServletResponse;  
  11.   
  12. import com.larson.tools.RegisterResultTool;  
  13.   
  14. public class RegisterServlet extends HttpServlet {  
  15.   
  16.   
  17.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  18.             throws ServletException, IOException {  
  19.   
  20.     }  
  21.   
  22.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  23.             throws ServletException, IOException {  
  24.         //1.获取输入输出流  
  25.         response.setContentType(“text/html;charset=UTF-8”);  
  26.         PrintWriter out = response.getWriter();  
  27.         InputStream in = request.getInputStream();  
  28.         //2.处理客户端发送的数据  
  29.         RegisterResultTool tool = new RegisterResultTool();  
  30.         String result = tool.register(in);  
  31.           
  32.         //3.向客户端写相应数据  
  33.         out.write(result);  
  34.         out.flush();  
  35.         out.close();  
  36.         in.close();  
  37.     }  
  38.   
  39.   
  40. }  

 servlet拿到客户端的数据inputStream,用一个工具类RegisterResultTool.java处理这些数据:

 

 

Java代码 

 

  1. package com.larson.tools;  
  2.   
  3. import java.io.InputStream;  
  4.   
  5. import javax.xml.parsers.SAXParserFactory;  
  6.   
  7. import org.xml.sax.InputSource;  
  8. import org.xml.sax.XMLReader;  
  9.   
  10. import com.larson.bean.UserInfo;  
  11. import com.larson.daoimpl.UserDao;  
  12. import com.larson.handler.RegisterHandler;  
  13.   
  14. /** 
  15.  * 处理客户端发送过来数据的类 
  16.  *  
  17.  * @author Larson 
  18.  *  
  19.  */  
  20. public class RegisterResultTool {  
  21.   
  22.     /** 
  23.      * 处理客户端发送过来数据的类 
  24.      * @param in 
  25.      *            客户端的流 
  26.      * @return 处理结果 
  27.      */  
  28.     public String register(InputStream in) {  
  29.         String result = null;  
  30.         StringBuilder sb = new StringBuilder();  
  31.         //1.获取解析工厂  
  32.         SAXParserFactory factory = SAXParserFactory.newInstance();  
  33.         XMLReader reader= null;  
  34.         try {  
  35.             //2.自定义解析过程  
  36.             reader = factory.newSAXParser().getXMLReader();  
  37.             RegisterHandler handler = new RegisterHandler();  
  38.             reader.setContentHandler(handler);  
  39.               
  40.             //3.开始解析客户端过来的输入流,并把数据封装到userInfo的bean中  
  41.             reader.parse(new InputSource(in));  
  42.             UserInfo user = handler.getUser();  
  43.               
  44.             //4.往服务器的数据库添加一条用户信息  
  45.             UserDao dao = new UserDao();  
  46.             dao.add(user);  
  47.               
  48.             //5.完成后给客户端反馈消息  
  49.             sb.append(“<info>”);  
  50.             sb.append(“regist_ok”);  
  51.             sb.append(“</info>”);  
  52.         } catch (Exception e) {  
  53.             //TODO 解析失败  
  54.             sb.append(“<info>”);  
  55.             sb.append(“regist_fail”);  
  56.             sb.append(“</info>”);  
  57.             e.printStackTrace();  
  58.         }  
  59.         result = sb.toString();  
  60.         return result;  
  61.     }  
  62.   
  63. }  

 再次过程中,我们需要自定义一个sax解析xml的handler对数据进行处理封装到bean文件中:

 

RegisterHandler.java:

 

Java代码 

 

  1. package com.larson.handler;  
  2.   
  3. import org.xml.sax.Attributes;  
  4. import org.xml.sax.SAXException;  
  5. import org.xml.sax.helpers.DefaultHandler;  
  6.   
  7. import com.larson.bean.UserInfo;  
  8.   
  9. public class RegisterHandler extends DefaultHandler {  
  10.     private UserInfo user;  
  11.     private String var=””;  
  12.       
  13.       
  14.     @Override  
  15.     public void startElement(String uri, String localName, String qName,  
  16.             Attributes attributes) throws SAXException {  
  17.         //遇到user标签就表示是一个user对象  
  18.         if(qName.equals(“user”))  
  19.             user = new UserInfo();  
  20.         super.startElement(uri, localName, qName, attributes);  
  21.     }  
  22.   
  23.     @Override  
  24.     public void endElement(String uri, String localName, String qName)  
  25.             throws SAXException {  
  26.         if(“username”.equals(qName))  
  27.             user.setUsername(var);  
  28.         if(“password”.equals(qName))  
  29.             user.setPassword(var);  
  30.         if(“nickname”.equals(qName))  
  31.             user.setNickname(var);  
  32.         if(“gender”.equals(qName))  
  33.             user.setGender(var);  
  34.           
  35.         //设置完临时属性置空  
  36.         var=””;  
  37.         super.endElement(uri, localName, qName);  
  38.     }  
  39.   
  40.     @Override  
  41.     public void characters(char[] ch, int start, int length)  
  42.             throws SAXException {  
  43.         var+=new String(ch, start, length);  
  44.         super.characters(ch, start, length);  
  45.     }  
  46.   
  47.     /** 
  48.      * 获取填充完属性的user对象 
  49.      * @return 
  50.      */  
  51.     public UserInfo getUser() {  
  52.         return user;  
  53.     }  
  54.   
  55. }  

 ,处理完毕以后,需要把这些数据写入到数据库,生成一条新的用户信息记录,因此需要些一个UserDao。,而我们习惯性用jdbcutils管理连接,这里为了代码可重用更好,我把所有修改的方法集合到一个update方法里面:JdbcUtils.java:

Java代码 

 

  1. package com.larson.tools;  
  2.   
  3. import java.io.InputStream;  
  4. import java.sql.Connection;  
  5. import java.sql.DriverManager;  
  6. import java.sql.PreparedStatement;  
  7. import java.sql.ResultSet;  
  8. import java.sql.SQLException;  
  9. import java.sql.Statement;  
  10. import java.util.Properties;  
  11.   
  12. import com.larson.handler.ResultSetHandler;  
  13.   
  14. /** 
  15.  * 数据库相关 
  16.  * @author Larson 
  17.  * 
  18.  */  
  19. public class JdbcUtils {  
  20.       
  21. //    private static ComboPooledDataSource ds = null;  
  22.     private static Connection conn;  
  23.       
  24.     static{  
  25.         try{  
  26.             InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream(“db.properties”);  
  27.             Properties properties = new Properties();  
  28.             properties.load(in);  
  29.             String url = properties.getProperty(“url”);  
  30.             String user = properties.getProperty(“user”);  
  31.             String passwd  = properties.getProperty(“password”);  
  32.             String driver =  properties.getProperty(“driver”);  
  33.               
  34.               
  35.             Class.forName(driver);  
  36.             conn = DriverManager.getConnection(url, user, passwd);  
  37.               
  38.               
  39. //          ds = new ComboPooledDataSource();  
  40. //          ds.setDriverClass(driver);  
  41. //          ds.setJdbcUrl(url);  
  42. //          ds.setUser(user);  
  43. //          ds.setPassword(passwd);  
  44. //            
  45. //          ds.setInitialPoolSize(10);  
  46. //          ds.setMinPoolSize(5);  
  47. //          ds.setMaxPoolSize(20);  
  48. //            
  49. //          ds = new ComboPooledDataSource();  
  50.               
  51.         }catch (Exception e) {  
  52.             throw new ExceptionInInitializerError(e);  
  53.         }  
  54.     }  
  55.       
  56.     /** 
  57.      * 获取连接 
  58.      * @return 
  59.      * @throws SQLException 
  60.      */  
  61.     public static Connection getConnection() throws SQLException{  
  62. //      return ds.getConnection();  
  63.         return conn;  
  64.     }  
  65.       
  66.     /** 
  67.      * 释放连接 
  68.      * @param conn 
  69.      * @param st 
  70.      * @param rs 
  71.      */  
  72.     public static void release(Connection conn,Statement st,ResultSet rs){  
  73.           
  74.         if(rs!=null){  
  75.             try{  
  76.                 rs.close();  
  77.             }catch (Exception e) {  
  78.                 e.printStackTrace();  
  79.             }  
  80.             rs = null;  
  81.   
  82.         }  
  83.         if(st!=null){  
  84.             try{  
  85.                 st.close();  
  86.             }catch (Exception e) {  
  87.                 e.printStackTrace();  
  88.             }  
  89.         }  
  90.         if(conn!=null){  
  91.             try{  
  92.                 conn.close();  
  93.             }catch (Exception e) {  
  94.                 e.printStackTrace();  
  95.             }  
  96.         }  
  97.     }  
  98.       
  99.       
  100.     /** 
  101.      * 替换dao中的增删改方法 
  102.      * @param sql 
  103.      * @param params 
  104.      * @throws SQLException 
  105.      */  
  106.     public static void update(String sql,Object params[]) throws SQLException{  
  107.         Connection conn = null;  
  108.         PreparedStatement st = null;  
  109.         ResultSet rs = null;  
  110.           
  111.         try{  
  112.             conn = getConnection();  
  113.             st = conn.prepareStatement(sql);  
  114.             for(int i=0;i<params.length;i++){  
  115.                 st.setObject(i+1, params[i]);  
  116.             }  
  117.             st.executeUpdate();  
  118.               
  119.         }finally{  
  120.             release(conn, st, rs);  
  121.         }  
  122.     }  
  123.       
  124.     /** 
  125.      * 替换所有dao中的查询   策略模式 
  126.      * @param sql 
  127.      * @param params 
  128.      * @param rsh 
  129.      * @return 
  130.      * @throws SQLException 
  131.      */  
  132.     public static Object query(String sql,Object params[],ResultSetHandler rsh) throws SQLException{  
  133.           
  134.         Connection conn = null;  
  135.         PreparedStatement st = null;  
  136.         ResultSet rs = null;  
  137.           
  138.         try{  
  139.             conn = getConnection();  
  140.             st = conn.prepareStatement(sql);  
  141.             for(int i=0;i<params.length;i++){  
  142.                 st.setObject(i+1, params[i]);  
  143.             }  
  144.             rs = st.executeQuery();  
  145.             return rsh.handler(rs);  
  146.               
  147.         }finally{  
  148.             release(conn, st, rs);  
  149.         }  
  150.     }  
  151. }  

 然后便是UserDao.java:

Java代码 

 

  1. package com.larson.daoimpl;  
  2.   
  3. import com.larson.bean.UserInfo;  
  4. import com.larson.exception.DaoException;  
  5. import com.larson.handler.BeanHandler;  
  6. import com.larson.tools.JdbcUtils;  
  7.   
  8. public class UserDao {  
  9.   
  10.     public void add(UserInfo user) {  
  11.         try {  
  12.             String sql = “insert into user(username,password,gender,nickname) values(?,?,?,?)”;  
  13.             Object params[] = {  user.getUsername(),  
  14.                     user.getPassword(), user.getGender(),user.getNickname() };  
  15.   
  16. for(Object obj:params)  
  17.     System.out.println(“userdao add—“+obj);  
  18.               
  19.             JdbcUtils.update(sql, params);  
  20.         } catch (Exception e) {  
  21.             throw new DaoException(e);  
  22.         }  
  23.     }  
  24.   
  25.     public void update(UserInfo user) {  
  26.         try {  
  27.             String sql = “update user set user=?,password=?,gender=?,nickname=? where id=?”;  
  28.             Object params[] = { user.getId(), user.getUsername(),  
  29.                     user.getPassword(), user.getNickname(), user.getId() };  
  30.             JdbcUtils.update(sql, params);  
  31.         } catch (Exception e) {  
  32.             throw new DaoException(e);  
  33.         }  
  34.     }  
  35.   
  36.     public void delete(String id) {  
  37.         try {  
  38.             String sql = “delete from user where id=?”;  
  39.             Object params[] = { id };  
  40.             JdbcUtils.update(sql, params);  
  41.         } catch (Exception e) {  
  42.             throw new DaoException(e);  
  43.         }  
  44.     }  
  45.   
  46.     public UserInfo find(String id) {  
  47.         try {  
  48.             String sql = “select * from user where id=?”;  
  49.             Object params[] = { id };  
  50.             return (UserInfo) JdbcUtils.query(sql, params, new BeanHandler(  
  51.                     UserInfo.class));  
  52.         } catch (Exception e) {  
  53.             throw new DaoException(e);  
  54.         }  
  55.     }  
  56.   
  57. }  

 为了方便,我把bean文件也贴出来:

userInfo.java:

Java代码 

 

  1. package com.larson.bean;  
  2.   
  3. public class UserInfo {  
  4.     private int id;  
  5.     private String username;  
  6.     private String password;  
  7.     private String gender;  
  8.     private String nickname;  
  9.   
  10.     public String getUsername() {  
  11.         return username;  
  12.     }  
  13.   
  14.     public void setUsername(String username) {  
  15.         this.username = username;  
  16.     }  
  17.   
  18.     public int getId() {  
  19.         return id;  
  20.     }  
  21.   
  22.     public void setId(int id) {  
  23.         this.id = id;  
  24.     }  
  25.   
  26.     public String getPassword() {  
  27.         return password;  
  28.     }  
  29.   
  30.     public void setPassword(String password) {  
  31.         this.password = password;  
  32.     }  
  33.   
  34.     public String getGender() {  
  35.         return gender;  
  36.     }  
  37.   
  38.     public void setGender(String gender) {  
  39.         this.gender = gender;  
  40.     }  
  41.   
  42.     public String getNickname() {  
  43.         return nickname;  
  44.     }  
  45.   
  46.     public void setNickname(String nickname) {  
  47.         this.nickname = nickname;  
  48.     }  
  49.   
  50. }  

 本来准备用数据库连接池的,可是老是报错,就是上面注释的那几行,有懂的人麻烦告诉我,感激不尽。

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图