14.Android学习之网络编程及Internet应用(一)

本文介绍了Android中使用HttpURLConnection进行HTTP网络编程的基本方法,包括发送GET和POST请求。强调了不在主线程进行网络操作的重要性,并给出了相关代码示例以及如何在本地搭建测试服务器的说明。

目录

14.网络编程及Internet应用(一)

1.通过HTTP访问网络

1-1.发送GET请求

1-2.发送POST请求


14.网络编程及Internet应用(一)

1.通过HTTP访问网络

在Android中也可以使用HTTP协议访问网络。例如,在使用应用宝App下载游戏时,或者刷新朋友圈时,都需要通过HTTP协议访问网络。

在Android中提供了两个用于HTTP通信的API,即HttpURLConnection和Apache的HttpClient。由于Android 6.0版本已经基本将HttpClient从SDK中移除了。所以这里主要介绍HttpURLConnection。

HttpURLConnection类位于java.net 包中,用于发送HTTP请求和获取HTTP响应。由于该类是抽象类,不能直接实例化对象,则需要使用URL的openConnection()方法来获得。例如,要创建一个http://www.example.com 网站对应的HttpURLConnection对象,可以使用下面的代码:

URL url = new URL("http://www.example.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

HttpURLConnection是URLConnection的一个子类,它在URLConnection的基础上提供了如表14.1所示的方法,从而方便发送和响应HTTP请求。

表14.1 HttpURLConnection常用的方法

方法描述
int getResponseCode()获取服务器的响应代码
String getResponseMessage()获取服务器的响应消息
String getRequestMethod()获取发送请求的方法
void setRequestMethod(String method)设置发送请求的方法

创建了HttpURLConnection对象后,就可以使用该对象发送HTTP请求了。

1-1.发送GET请求

使用HttpURLConnection对象发送请求时,默认发送的就是GET请求。因此,发送GET请求比较简单,只需要在指定连接地址时,先将要传递的参数通过“?参数名=参数值”的形式进行传递(多个参数间使用英文半角的“&”符号分隔。例如,要传递用户名和E-mail地址这两个参数,可以使用“?user=abc&email= abc@qq.com”实现),然后获取输入流中的数据,并关闭连接即可。

注:使用HTTP协议访问网络就是客户端与服务器的通信,所以运行本章实例不仅需要创建客户端app实例,还需要创建简单的后台服务器。

(1) 永远不要在主线程上执行网络调用。

(2) 在Service而不是Activity 中执行网络操作。

例 :

 MainActivity.java

package com.example.getrequest;
​
import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
​
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
​
public class MainActivity extends Activity {
    private EditText content;                    //定义一个输入文本内容的编辑框对象
    private Handler handler;                    //定义一个android.os.Handler对象
    private String result = "";                 //定义一个代表显示内容的字符串
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
​
        content = (EditText) findViewById(R.id.main_et1);    //获取输入文本内容的EditText组件
        final TextView resultTV = (TextView) findViewById(R.id.main_tv1);    //获取显示结果的TextView组件
        Button button = (Button) findViewById(R.id.main_btn1);    //获取“发表”按钮组件
        button.setOnClickListener(new View.OnClickListener() {  //单击发送按钮,实现读取服务器微博信息
            @Override
            public void onClick(View v) {
                //判断输入内容是否为空,为空给出提示消息,否则访问服务器
                if ("".equals(content.getText().toString())) {
                    Toast.makeText(MainActivity.this, "请输入要发表的内容!",
                            Toast.LENGTH_SHORT).show();    //显示消息提示
                    return;
                }
                handler = new Handler() {  //将服务器中的数据,显示在UI界面中
                    @Override
                    public void handleMessage(Message msg) {
                        if (result != null) {          //如果服务器返回结果不为空
                            resultTV.setText(result); // 显示获得的结果
                            content.setText("");        //清空文本框
                        }
                        super.handleMessage(msg);
                    }
                };
​
                new Thread(new Runnable() {  // 创建一个新线程,用于发送并读取微博信息
                    public void run() {
                        send();    //调用send()方法,用于发送文本内容到Web服务器
                        Message m = handler.obtainMessage(); // 获取一个Message
                        handler.sendMessage(m); // 发送消息
                    }
                }).start(); // 开启线程
            }
        });
​
    }
​
    public void send() {  //创建send()方法,用于建立一个HTTP连接,并将输入的内容发送到Web服务器上,再读取服务器的处理结果
        String target = "";
        String test=base64(content.getText().toString().trim());
        target = "http://192.168.3.19:8080/example/get.jsp?content="
                +test.substring(0,test.length()-3);    //要访问的URL地址
        Log.i("test",test.trim());
        URL url;
        try {
            url = new URL(target);
            Log.i("test", url.toString());
            HttpURLConnection urlConn = (HttpURLConnection) url
                    .openConnection();    //创建一个HTTP连接
            InputStreamReader in = new InputStreamReader(
                    urlConn.getInputStream()); // 获得读取的内容
            BufferedReader buffer = new BufferedReader(in); // 获取输入流对象
            String inputLine = null;
            //通过循环逐行读取输入流中的内容
            while ((inputLine = buffer.readLine()) != null) {
                result += inputLine+"\n";
            }
            Log.i("test01",buffer.toString());
            in.close();    //关闭字符输入流对象
            urlConn.disconnect();    //断开连接
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
​
    public String base64(String content) {  //对字符串进行Base64编码
​
        try {
            //对字符串进行Base64编码
            content = Base64.encodeToString(content.getBytes("utf-8"), Base64.DEFAULT);
            content = URLEncoder.encode(content, "utf-8");    //对字符串进行URL编码
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return content;
    }
​
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:padding="18dp"
    android:background="@drawable/bg"
    android:orientation="vertical">
    
    <EditText
        android:id="@+id/main_et1"
        android:hint="输入想要发表的内容~~~"
        android:textSize="22sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
​
    <Button
        android:id="@+id/main_btn1"
        android:text="发表"
        android:background="#0373EC"
        android:textSize="22sp"
        android:layout_marginTop="175dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
​
<!--    滚动视图-->
    <ScrollView
        android:layout_gravity="center_horizontal"
        android:padding="10dp"
        android:layout_marginTop="40dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/main_tv1"
            android:textSize="22sp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </ScrollView>
</LinearLayout>

AndroidManifest.xml

<!--访问网络-->
<uses-permission android:name="android.permission.INTERNET"/>

<application>节点下(Android9.0以上联网需要添加):

android:usesCleartextTraffic="true"

在Tomcat安装路径的webapps文件夹中新建一个文件夹,命名为example,在example文件夹下新建一个.jsp文件,命名为get.jsp,在get.jsp中编写代码:

<%@page contentType="text/html; charset=utf-8" language="java" import="java.util.Base64,java.util.Base64.Decoder"%>
<%
String content=request.getParameter("content");//获取输入的微博信息
 if(content!=null){
    Decoder decoder= Base64.getDecoder();
    content=new String(decoder.decode(content),"utf-8");    //进行base64解码
String date=new java.util.Date().toLocaleString();  //获取系统时间
%>
<%="[Lisa]于 "+date+" 发表一条微博,内容如下:"%>
<%=content%>
<% }%>

运行Tomcat,连接真机运行Android项目。

注:真机需要能够连接到客户端的Tomcat服务器才能运行该项目,步骤如下:

(1)关闭电脑的防火墙

 (2)电脑创建热点,用手机连接到电脑热点

设置->网络和Internet->移动热点

 (3)用手机浏览器访问Tomcat网址,如果能显示Tomcat首页即为连接成功

1-2.发送POST请求

在Android中,使用HttpURLConnection类发送请求时,默认采用的是GET请求,如果要发送POST请求,需要通过其setRequestMethod()方法进行指定。例如,创建一个 HTTP 连接,并为该连接指定请求的发送方式为POST,可以使用下面的代码:

HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();//创建一个HTTP连接
urlConn.setRequestMethod("POST");//指定请求方式为POST

发送POST请求要比发送GET请求复杂一些,它需要通过HttpURLConnection类及其父类URLConnection提供的方法设置相关内容,常用的方法如表14.2 所示。

表14.2 发送POST请求时常用的方法

方法描述
setDoInput(boolean newValue)用于设置是否向连接中写入数据,如果参数值为 true,表示写入数据;否则不写入数据
setDoOutput(boolean newValue)用于设置是否从连接中读取数据,如果参数值为true,表示读取数据;否则不读取数据
setUseCaches(boolean newValue)用于设置是否缓存数据,如果参数值为true,表示缓存数据;否则表示禁用缓存
setInstanceFollowRedirects(boolean followRedirects)用于设置是否应该自动执行HTTP重定向,参数值为true时,表示自动执行;否则不自动执行
setRequestProperty(String field, String newValue)用于设置一般请求属性,例如,要设置内容类型为表单数据,可以进行以下设置setRequestProperty("Content-Type","application/x-www-form-urlencoded")

例:

 MainActivity.java

package com.example.postrequest;
​
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
​
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
​
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
​
public class MainActivity extends AppCompatActivity {
    private EditText edit_Username;//输入账号的编辑框
    private EditText edit_Password;//输入密码的编辑框
    private Handler handler;
    private String result="";//显示内容
​
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActionBar actionBar=getSupportActionBar();
        actionBar.hide();
        edit_Username=findViewById(R.id.main_username);
        edit_Password=findViewById(R.id.main_password);
        ImageButton btn_login=findViewById(R.id.main_login);
        btn_login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if("".equals(edit_Username.getText().toString()) ||
                        "".equals(edit_Password.getText().toString())){
                    Toast.makeText(MainActivity.this, "请填写账号或密码!", Toast.LENGTH_SHORT).show();
                    return;
                }
​
                handler=new Handler(){
​
                    @Override
                    public void handleMessage(@NonNull Message msg) {
                        //如果服务器返回值为“ok”证明账号密码正确
                        if("ok".equals(result)){
                            //跳转登录后界面
                            Log.i("test",result);
                            Intent intent=new Intent(MainActivity.this,MessageActivity.class);
                            startActivity(intent);
                        }else {
                            Toast.makeText(MainActivity.this, "请填写正确的账号和密码!", Toast.LENGTH_SHORT).show();
                        }
                        super.handleMessage(msg);
                    }
                };
​
                //创建一个新线程,用于从网络上获取数据
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        send();
                        Message message=handler.obtainMessage();
                        handler.sendMessage(message);//发送消息
                    }
                }).start();//开启线程
            }
        });
    }
​
    //建立HTTP连接,发送POST请求到服务器并读取服务器的处理结果
    public void send(){
        //要提交的服务器地址
        String target="http://192.168.3.19:8080/example/post.jsp";
        URL url;
        try {
            url=new URL(target);//创建URL对象
            HttpURLConnection urlConnection= (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("POST");//指定使用POST请求方式
            urlConnection.setDoInput(true);//允许向连接写入数据
            urlConnection.setDoOutput(true);//允许向连接读取数据
            urlConnection.setUseCaches(false);//禁止缓存
            urlConnection.setInstanceFollowRedirects(true);//自动执行HTTP重定向
            urlConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");//设置内容类型
                    DataOutputStream outputStream=new DataOutputStream(urlConnection.getOutputStream());//获取输出流
            String param="username="+ URLEncoder.encode(edit_Username.getText().toString(),"utf-8")
                    +"&password="+URLEncoder.encode(edit_Password.getText().toString(),"utf-8");
            outputStream.writeBytes(param);//将要传递的数据写入输入流
            outputStream.flush();//输出缓存
            outputStream.close();//关闭输出流
            if(urlConnection.getResponseCode()==HttpURLConnection.HTTP_OK){
                InputStreamReader inputStreamReader=new InputStreamReader(urlConnection.getInputStream());//读取内容
                BufferedReader bufferedReader=new BufferedReader(inputStreamReader);
                String inputLine=null;
                //逐行读取输入流中的内容
                while((inputLine=bufferedReader.readLine())!=null){
                    result+=inputLine;
                }
                inputStreamReader.close();//关闭字节输入流
            }
            urlConnection.disconnect();//断开连接
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

AndroidManifest.xml

<!--    访问网络-->
<uses-permission android:name="android.permission.INTERNET"/>

<application>节点下:

android:usesCleartextTraffic="true"

在Tomcat安装路径的webapps文件夹中新建一个文件夹,命名为example,在example文件夹下新建一个.jsp文件,命名为post.jsp,在post.jsp中编写代码:

<%@ page contentType="text/html; charset=utf-8" language="java" %>
<%String password=request.getParameter("password");//获取输入的密码
String username=request.getParameter("username");//获取输入的用户名
if(password!=null && username!=null){
username=new String(username.getBytes("iso-8859-1"),"utf-8");   //对用户名进行转码
password=new String(password.getBytes("iso-8859-1"),"utf-8");   //对密码进行转码
if("test".equals(username)&&"123".equals(password)){
%>
<%="ok"%>
<%}%>
<%}%>

运行Tomcat,连接真机运行Android项目。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值