• android菜鸟学习笔记24----与服务器端交互(一)使用HttpURLConnection和HttpClient请求服务端数据


    主要是基于HTTP协议与服务端进行交互。

    涉及到的类和接口有:URL、HttpURLConnection、HttpClient等

    URL

     

    使用一个String类型的url构造一个URL对象,如:

    URL url = new URL(http://10.0.2.2/index.php);

     

    openConnection()方法返回一个对指定url的资源的连接。返回类型是URLConnection,但是,由于这里我们一般用的是http协议,所以返回的实际是HttpURLConnection对象,故一般可以进行类型转换。

    HttpURLConnection conn = (HttpURLConnection)url.openConnection();

    HttpURLConnection:

    继承自URLConnection,常用方法有:

     

    getInputStream()方法用来获取用来从网络连接中读取数据的输入流。

     

    getOutputStream()方法用于获取用于向网络连接中写入数据的输出流。

     

    setDoOutput()和setDoInput()方法分别用来设置是否允许向网络写入或读取数据。

     

    setReadTimeout()方法用于设置读取数据超时时限。

     

    setConnectTimeout()方法用于设置网络连接超时时限。

     

    setRequestMethod()方法用于设置请求的方法,一般常用”GET”或”POST”。

     

    getResponseCode()和getResponseMessage()方法分别用来获取服务端的响应码及响应信息字符串描述。

     

    Disconnect()方法用于关闭网络连接。

    1.使用HttpURLConnection与服务端进行交互

    布局文件代码:

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2 
     3     xmlns:tools="http://schemas.android.com/tools"
     4 
     5     android:layout_width="match_parent"
     6 
     7     android:layout_height="match_parent"
     8 
     9     android:orientation="vertical"
    10 
    11     tools:context="cn.csc.start.MainActivity" >
    12 
    13     <EditText
    14 
    15         android:id="@+id/et_username"
    16 
    17         android:layout_width="match_parent"
    18 
    19         android:layout_height="wrap_content"
    20 
    21         android:hint="@string/et_username_text"/>
    22 
    23     <EditText
    24 
    25         android:id="@+id/et_password"
    26 
    27         android:layout_width="match_parent"
    28 
    29         android:layout_height="wrap_content"
    30 
    31         android:inputType="textPassword"
    32 
    33         android:hint="@string/et_password_text"/>
    34 
    35     <Button
    36 
    37         android:id="@+id/btn_login"
    38 
    39         android:layout_width="wrap_content"
    40 
    41         android:layout_height="wrap_content"
    42 
    43         android:text="@string/btn_text"
    44 
    45         />
    46 
    47 </LinearLayout>

    一个简单的php文件,模拟服务器端:

     1 <?php
     2 
     3 if(isset($_REQUEST["username"])&& isset($_REQUEST["password"])){
     4 
     5       $username = $_REQUEST["username"];
     6 
     7       $password = $_REQUEST["password"];
     8 
     9       if($username == "zhangsan" && $password == "123"){
    10 
    11            echo "login success";
    12 
    13       }else{
    14 
    15            echo "login failure";
    16 
    17       }
    18 
    19 }else{
    20 
    21       echo "no field allowed empty string";
    22 
    23 }
    24 
    25 ?>

    客户端提交用户名密码,客户端返回登录的结果。

     注意,在模拟器中用IP:10.0.2.2代表电脑的IP地址。

    1.1使用GET方式与服务端进行交互

     1 public class MainActivity extends ActionBarActivity implements OnClickListener {
     2 
     3  
     4 
     5     protected static final int OK = 0;
     6 
     7       protected static final String TAG = "MYLOG";
     8 
     9       private EditText et_username;
    10 
    11       private EditText et_password;
    12 
    13       @Override
    14 
    15     protected void onCreate(Bundle savedInstanceState) {
    16 
    17         super.onCreate(savedInstanceState);
    18 
    19         setContentView(R.layout.activity_main);
    20 
    21         Button btn = (Button) findViewById(R.id.btn_login);
    22 
    23         btn.setOnClickListener(this);
    24 
    25         et_username = (EditText) findViewById(R.id.et_username);
    26 
    27         et_password = (EditText) findViewById(R.id.et_password);
    28 
    29 }
    30 
    31   @Override
    32 
    33   public void onClick(View view) {
    34 
    35         // TODO Auto-generated method stub
    36 
    37         if(view.getId() == R.id.btn_login){
    38 
    39              get_test();
    40 
    41         }
    42 
    43   }
    44 
    45 private void get_test() {
    46 
    47         // TODO Auto-generated method stub
    48 
    49         String username = et_username.getText().toString();
    50 
    51         String password = et_password.getText().toString();
    52 
    53         try {
    54 
    55              URL url = new URL("http://10.0.2.2/index.php?username="+username+"&password="+password);
    56 
    57              HttpURLConnection conn =  (HttpURLConnection) url.openConnection();
    58 
    59              conn.setRequestMethod("GET");
    60 
    61              conn.setConnectTimeout(5000);
    62 
    63              conn.setReadTimeout(5000);
    64 
    65              if(conn.getResponseCode() == 200){
    66 
    67                    InputStream is = conn.getInputStream();
    68 
    69                    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    70 
    71                    String result = br.readLine();
    72 
    73                    Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
    74 
    75                    conn.disconnect();
    76 
    77              }
    78 
    79             
    80 
    81         } catch (Exception e) {
    82 
    83              // TODO Auto-generated catch block
    84 
    85              e.printStackTrace();
    86 
    87         }
    88 
    89   }
    90 
    91 }

    1.2使用POST方式与服务端进行交互

    添加一个post_test方法:

     1 private void post_test(){
     2 
     3         try {
     4 
     5              URL url = new URL("http://10.0.2.2/index.php");
     6 
     7              HttpURLConnection conn = (HttpURLConnection) url.openConnection();
     8 
     9              conn.setRequestMethod("POST");
    10 
    11              conn.setDoOutput(true);
    12 
    13              conn.setConnectTimeout(5000);
    14 
    15              conn.setReadTimeout(5000);
    16 
    17              String username = et_username.getText().toString();
    18 
    19              String password = et_password.getText().toString();
    20 
    21              OutputStream os = conn.getOutputStream();
    22 
    23              String req = "username="+username+"&password="+password;
    24 
    25             
    26 
    27              os.write(req.getBytes());
    28 
    29              if(conn.getResponseCode()== 200){
    30 
    31                    InputStream is = conn.getInputStream();
    32 
    33                    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    34 
    35                    String result = br.readLine();
    36 
    37                    Toast.makeText(this, result, Toast.LENGTH_LONG).show();
    38 
    39                    is.close();
    40 
    41                    os.close();
    42 
    43                    conn.disconnect();
    44 
    45              }              
    46 
    47         } catch (Exception e) {
    48 
    49              // TODO Auto-generated catch block
    50 
    51              e.printStackTrace();
    52 
    53         }
    54 
    55 }

    然后在onClick()中调用该方法。

    注意到,这里由于只有一个线程,即在主线程(UI线程)中请求服务器,若有耗时操作,此时应用是不会响应用户操作的,这就是传说中的ANR异常

    所以,就必须新建一个子线程执行耗时操作。

    修改get_test()方法,新建一个线程执行该方法中的操作:

     1 private void get_test() {
     2 
     3         new Thread(new Runnable() {
     4 
     5              @Override
     6 
     7              public void run() {
     8 
     9                    String username = et_username.getText().toString();
    10 
    11                    String password = et_password.getText().toString();
    12 
    13                    try {
    14 
    15                         URL url = new URL("http://10.0.2.2/index.php?username="+username+"&password="+password);
    16 
    17                         HttpURLConnection conn =  (HttpURLConnection) url.openConnection();
    18 
    19                         conn.setRequestMethod("GET");
    20 
    21                         conn.setConnectTimeout(5000);
    22 
    23                         conn.setReadTimeout(5000);
    24 
    25                         if(conn.getResponseCode() == 200){
    26 
    27                               InputStream is = conn.getInputStream();
    28 
    29                               BufferedReader br = new BufferedReader(new InputStreamReader(is));
    30 
    31                               String result = br.readLine();
    32 
    33                               Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
    34 
    35                               conn.disconnect();
    36 
    37                         }
    38 
    39                        
    40 
    41                    } catch (Exception e) {
    42 
    43                         // TODO Auto-generated catch block
    44 
    45                         e.printStackTrace();
    46 
    47                    }
    48 
    49              }
    50 
    51         }).start();
    52 
    53   }

    这时重新运行程序,会发现新的问题:

    提示,无法在非UI线程中进行UI操作,因为这样不安全

    为了解决这个问题,android提供了一套消息处理机制,很像win32中的消息循环机制。

    下面简单说明下这套机制:

     

    引入消息机制后:

     

    这套消息机制主要涉及到两个类:HandlerMessage

    Handler

    一般需要自定义Handler继承Handler类,并重写消息处理方法,一般将其对象在UI线程中定义,这样就可以在其消息处理方法中进行UI操作了。

    常用方法:

     

    消息处理回调函数,一般自定义的Handler类都要重写该方法,添加自己需要的消息处理业务逻辑。

     

    sendMessage(Message msg)发送一条消息。

    Message

    消息类,其对象作为消息实体被handler对象发送或者接收处理。

     

    使用无参构造创建一个消息对象,一般在发送之前还需要设置其两个主要的属性:

     

    what属性,可以用来存放消息的类型

     

    obj属性,可以用来存放想要传送的消息内容或者传递的其他参数等。

    修改上面的应用,添加消息处理机制:

    在MainActivity中添加个Handler类型的私有属性:

     1 private Handler handler = new Handler(){
     2 
     3            public void handleMessage(android.os.Message msg) {
     4 
     5                  if(msg.what == OK){
     6 
     7                       String str = msg.obj.toString();
     8 
     9                       Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show();
    10 
    11                      
    12 
    13                  }
    14 
    15            }
    16 
    17 };

    重写的消息处理函数,很简单,就是把服务端返回的信息通过Toast显示出来。

    添加一个方法,新建线程请求服务端数据,并通过消息机制发送消息:

     1 private void multi_thread_test(){
     2 
     3            new Thread(new Runnable() {
     4 
     5                 
     6 
     7                  @Override
     8 
     9                  public void run() {
    10 
    11                       // TODO Auto-generated method stub
    12 
    13                       try {
    14 
    15                             URL url = new URL("http://10.0.2.2/index.php");
    16 
    17                             HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    18 
    19                             conn.setRequestMethod("POST");
    20 
    21                             conn.setDoOutput(true);
    22 
    23                             conn.setConnectTimeout(5000);
    24 
    25                             conn.setReadTimeout(5000);
    26 
    27                             String username = et_username.getText().toString();
    28 
    29                             String password = et_password.getText().toString();
    30 
    31                             OutputStream os = conn.getOutputStream();
    32 
    33                             String req = "username="+username+"&password="+password;
    34 
    35                            
    36 
    37                             os.write(req.getBytes());
    38 
    39                             if(conn.getResponseCode()== 200){
    40 
    41                                   InputStream is = conn.getInputStream();
    42 
    43                                   BufferedReader br = new BufferedReader(new InputStreamReader(is));
    44 
    45                                   String result = br.readLine();
    46 
    47                                   Message msg = new Message();
    48 
    49                                   msg.what = OK;
    50 
    51                                   msg.obj = result;
    52 
    53                                   handler.sendMessage(msg);
    54 
    55                                   is.close();
    56 
    57                                   os.close();
    58 
    59                                   conn.disconnect();
    60 
    61                             }                    
    62 
    63                       } catch (Exception e) {
    64 
    65                             // TODO Auto-generated catch block
    66 
    67                             e.printStackTrace();
    68 
    69                       }
    70 
    71                  }
    72 
    73            }).start();
    74 
    75 }

    这样,在请求服务端数据时,应用还能响应用户的交互。

    2.还有另一种与服务端进行交互的方式,那就是使用HttpClient

    一般通过:

     HttpClient client = new defaultHttpClient() 构造出HttpClient对象。

    HttpClient类最主要的一个方法就是execute()方法。

     

    常用的是只有一个参数的重载形式,注意到其参数类型是HttpUriRequest类型。

    查看帮助手册:

     

    HttpUriRequest是一个接口

     

    已知的直接实现类,有那么多个,最常用的是HttpGet和HttpPost,从名字中便可知道,一个用于get方式与服务端交互,一个用于post方式与服务端交互。

    HttpGet的使用比较简单

     

    一般直接使用传入String类型的url构造出HttpGet对象,然后作为execute()的参数即可完成get方式请求。

    HttpPost的使用要稍微麻烦一点,因为GET方式直接在URL中传入了请求参数,而POST方式需要另外一种传参方式。

    POST方式的参数需要使用一个List<NameValuePair>类型的对象传递,

    NameValuePair是一个接口,一般使用的是其直接实现类BasicNameValuPair类:

    如:

    1 List<NameValuePair> params = new ArrayList<NameValuePair>();
    2 
    3 params.add(new BasicNameValuePair("username", username));
    4 
    5 params.add(new BasicNameValuePair("password", password));

    要POST的参数存储完成,如何通过HttpPost提交呢?

    注意到,帮助手册中关于HttpPost的信息:

     

    HttpPost是通过继承HttpEntitiyEnclosingRequestBase类间接实现HttpUriRequest接口的。

    该类中有一个方法:

     

    可以通过setEntity()方法将参数传递给HttpPost对象,具体做法如下:

    1 UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params,"utf-8");
    2 
    3 httppost.setEntity(entity);

    下面在MainActivity中添加方法,通过HttpClient方法与服务端进行交互:

     1 private void client_get_test(){
     2 
     3            new Thread(new Runnable() {
     4 
     5                 
     6 
     7                  @Override
     8 
     9                  public void run() {
    10 
    11                       // TODO Auto-generated method stub
    12 
    13                       String username = et_username.getText().toString();
    14 
    15                       String password = et_password.getText().toString();
    16 
    17                       HttpClient client = new DefaultHttpClient();
    18 
    19                       HttpGet get = new HttpGet("http://10.0.2.2/index.php?username="+username+"&password="+password);
    20 
    21                       try {
    22 
    23                             HttpResponse response = client.execute(get);
    24 
    25                             if(response.getStatusLine().getStatusCode() == 200){
    26 
    27                                   HttpEntity entity = response.getEntity();
    28 
    29                                   String result = EntityUtils.toString(entity, "utf-8");
    30 
    31                                   Message msg = new Message();
    32 
    33                                   msg.what = OK;
    34 
    35                                   msg.obj = result;
    36 
    37                                   handler.sendMessage(msg);
    38 
    39                             }
    40 
    41                       } catch (ClientProtocolException e) {
    42 
    43                             // TODO Auto-generated catch block
    44 
    45                             e.printStackTrace();
    46 
    47                       } catch (IOException e) {
    48 
    49                             // TODO Auto-generated catch block
    50 
    51                             e.printStackTrace();
    52 
    53                       }
    54 
    55                  }
    56 
    57            }).start();
    58 
    59       }

    使用HttpClient采用GET方式向服务端请求数据

     1 private void client_post_test(){
     2 
     3            new Thread(new Runnable() {
     4 
     5                 
     6 
     7                  @Override
     8 
     9                  public void run() {
    10 
    11                       // TODO Auto-generated method stub
    12 
    13                      
    14 
    15                       try {
    16 
    17                             String username = et_username.getText().toString();
    18 
    19                             String password = et_password.getText().toString();
    20 
    21                             HttpClient client = new DefaultHttpClient();
    22 
    23                             HttpPost post = new HttpPost("http://10.0.2.2/index.php");
    24 
    25                             List<NameValuePair> params = new ArrayList<NameValuePair>();
    26 
    27                             params.add(new BasicNameValuePair("username", username));
    28 
    29                             params.add(new BasicNameValuePair("password", password));
    30 
    31                             UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params,"utf-8");
    32 
    33                             post.setEntity(entity);
    34 
    35                             HttpResponse response = client.execute(post);
    36 
    37                             if(response.getStatusLine().getStatusCode() == 200){
    38 
    39                                   HttpEntity entity1 = response.getEntity();
    40 
    41                                   String result = EntityUtils.toString(entity1, "utf-8");
    42 
    43                                   Message msg = new Message();
    44 
    45                                   msg.what = OK;
    46 
    47                                   msg.obj = result;
    48 
    49                                   handler.sendMessage(msg);
    50 
    51                             }
    52 
    53                       } catch (ClientProtocolException e) {
    54 
    55                             // TODO Auto-generated catch block
    56 
    57                             e.printStackTrace();
    58 
    59                       } catch (IOException e) {
    60 
    61                             // TODO Auto-generated catch block
    62 
    63                             e.printStackTrace();
    64 
    65                       }
    66 
    67                  }
    68 
    69            }).start();
    70 
    71 }

    使用HttpClient采用POST方式向服务端请求数据。

    以上就是向服务端请求数据的简单学习。

  • 相关阅读:
    GridView
    母版页
    Ajax完整结构和删除
    Ajax1
    JQuery动画
    JQuery基础
    LinQ高级查询
    C#简单的学籍管理系统(数据库变更由原来的SQLserver改为SqLite)
    C#两个数只能进行+1,-1,*2操作。求使得两个数相等的最小步骤
    C#求最小公倍数与最大公约数
  • 原文地址:https://www.cnblogs.com/dqrcsc/p/4643878.html
Copyright © 2020-2023  润新知