Android使用HttpURLConnection实现网络访问流程

目录
  • 一、管理网络状态
  • 二、HTTP协议
  • 三、HttpURLConnection
  • 四、GET和POST请求方式
  • 五、做个实验

一、管理网络状态

使用网络进行数据通信前,需要先获取网络状态。

使用ConnectivityManager获取网络状态步骤:

1.获取ConnectivityManager对象

2.获取当前活动的网络NetworkInfo对象

3.判断当前网络状态是否为连接状态

4.在AndroidMainfest.xml中添加访问当前网络状态权限

//使用ConnectivityManager检查网络状态步骤
    private boolean checkNetworkState() {
        ConnectivityManager connectivityManager = (ConnectivityManager) this.getSystemService(CONNECTIVITY_SERVICE);//1.通过系统服务获取ConnectivityManager类的对象
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();//2.调用getActiveNetworkInfo()获取当前活动的网络NetworkInfo对象
        if (networkInfo==null || networkInfo.isConnected()==false) {//3.判断当前网络状态是否为连接状态,如果当前没有网络是活动的,则返回null
            return false;
        }else {
            return true;
        }
    }
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.httpurlexestud">
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><!--检查网络状态步骤4.添加访问当前网络状态权限-->
    <uses-permission android:name="android.permission.INTERNET"/><!--增加访问网络授权声明-->
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".WelcomeActivity"></activity>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

二、HTTP协议

1.HTTP(Hyper Text Transfer Protocol) 即超文本传输协议,是一种详细规定了客户端和万维网(www,World Wide Web)服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议。

2.HTTP协议是一种请求/响应式的协议。当客户端与服务器端建立连接后,向服务器端发送的请求,称作HTTP请求;当服务器端接收到请求后会做出响应,称为HTTP响应。

三、HttpURLConnection

HttpURLConnection类位于java.net内,提供了基于HTTP的网络访问方法。

使用HttpURLConnection访问HTTP资源的主要操作步骤:

1.利用URL地址实例化URL类

2.由URL类创建HttpURLConnection对象

3.以GET/POST方式向服务器发送请求

4.接收服务器响应

5.关闭连接

HTTP协议使用注意事项:

1.使用“ .setRequestMethod(" "); ”设置请求方式

2.使用“ .connect(); ”连接网络。请求行、请求头的设置必须放在网络连接前

3.“ .getInputStream() ”只是得到一个流对象,并不是数据。我们需要从流中读取数据,从流中读取数据的操作必须放在子线程

4.“ .getInputStream() ”得到一个流对象,从这个流对象中只能读取一次数据,第二次读取时将会得到空数据

四、GET和POST请求方式

1.GET方式是以实体的方式得到由请求URL所指向的资源信息,它向服务器提交的参数跟在请求URL后面。使用GET方式访问网络URL的长度一般要小于1K

2.POST方式向服务器发送请求时需要在请求后附加实体,它向服务器提交的参数在请求后的实体中。POST方式对URL的长度没有限制

3.采用POST方式提交数据时,用户在浏览器中看不到向服务器提交的请求参数,因此POST方式要比GET方式相对安全。

4.GET重点在从服务器上获取资源,POST重点在向服务器发送数据。

5.GET传输的数据量小,因为受URL长度限制,但效率较高;POST没有此限制,可以传输大量数据,所以上传文件时只能用POST方式。

6.GET方式只能支持ASCII字符,向服务器传的中文字符可能会乱码;POST支持标准字符集,可以正确传递中文字符。

注意事项:

1.所有内容都需要访问网络才能进行发送或者获取,因此需要配置文件AndroidMainfest.xml文件中添加访问网络的权限(第一部分里已给出代码)。

2.实际开发中,手机端与服务器端进行交互的过程中,避免不了要提交中文到服务器,这时就会出现中文乱码的情况。因此,无论是GET方式还是POST方式提交参数时都要对参数进行编码。需要注意的是,编码方式必须与服务器解码方式一致。同样,在获取服务器返回的中文字符时,也需要用指定格式进行解码。

(1)以GET方式提交数据

/*一、GET方式步骤:
                                1.把用户名和密码拼接成以get方式向服务器发送请求的URL字符串
                                2.使用url的openConnection()方法获得HttpURLConnection对象
                                3.设置HttpURLConnection对象的请求方式、超时等,并调用connect()建立连接
                                4.得到响应码并判断连接正常后,通过getInputStream()方法获得携带服务器返回信息的输入流,从流中读取出服务器返回值,并向handler发送消息
                                5.断开连接*/
                                String urlStr = "http://192.192.192.192:8080/TestServer/servlet/Login?name="+
                                        URLEncoder.encode(name)+
                                        "&pass="+URLEncoder.encode(pwd);//将用户名和密码拼在指定资源路径后面,并对用户名和密码进行编码
                                try {//使用try-catch-finally捕获异常
                                    url = new URL(urlStr);//在URL的构造方法中传入要访问资源的路径
                                    uc = (HttpURLConnection) url.openConnection();//返回一个HttpURLConnection对象
                                    uc.setRequestMethod("GET");//设置GET请求方式
                                    uc.setConnectTimeout(5000);//设置超时时间
                                    uc.connect();//连接
                                    int code = uc.getResponseCode();//得到响应码(获取HTTP状态码)
                                    if (code == HttpURLConnection.HTTP_OK) {//4.得到响应码并判断连接正常后,通过getInputStream()方法获得携带服务器返回信息的输入流,从流中读取出服务器返回值,并向handler发送消息
                                        System.out.println(uc.getResponseCode());//控制台输出
                                        InputStream inputStream = uc.getInputStream();//得到响应流(通过getInputStream()方法获取携带服务器返回信息的输入流)
                                        int i = inputStream.read();
                                        System.out.println(i);//控制台显示是0还是1,以ASCII码形式显示
                                        //通过Message和handler.sendMessage()将返回结果传递给UI线程
                                        Message message = Message.obtain();//从服务器返回的数据,1.获取可用的Message对象
                                        message.arg1 =i;//2.通过message的arg1传递参数
                                        handler.sendMessage(message);//发送至主界面显示
                                    }else {
                                        System.out.println(uc.getResponseCode());//控制台输出
                                        Message message = Message.obtain();
                                        message.arg1 =2;
                                        handler.sendMessage(message);
                                    }
                                }catch (Exception e) {
                                    e.printStackTrace();
                                }finally {
                                    if (uc != null) {
                                        uc.disconnect();//关闭HTTP连接
                                    }
                                }

(2)以POST方式提交数据

/*二、POST方式步骤:
                                1.通过URL字符串创建URL对象
                                2.使用url的openConnection()方法获得HttpURLConnection对象
                                3.设置HttpURLConnection对象的请求方式、超时、请求头数据提交方式等,并调用connect()建立连接
                                4.通过getOutputStream()获得输出流往服务器写数据
                                5.得到响应码并判断连接正常后,通过getInputStream()方法获得携带服务器返回信息的输入流,从流中读取出服务器返回值,并向handler发送消息
                                6.断开连接*/
                                String urlStr = "http://192.192.192.192:8080/TestServer/servlet/Login";
                                try {//使用try-catch-finally捕获异常
                                    url = new URL(urlStr);//在URL的构造方法中传入要访问资源的路径
                                    uc = (HttpURLConnection) url.openConnection();//返回一个HttpURLConnection对象
                                    uc.setRequestMethod("POST");//设置POST请求方式
                                    uc.setConnectTimeout(5000);//设置超时时间
                                    String data = "name="+ URLEncoder.encode(name) +
                                            "&pass="+URLEncoder.encode(pwd);
                                    uc.setRequestProperty("Content-Type","application/x-www-form-urlencoded");//设置请求头数据提交方式,这里以form表单形式提交
                                    uc.setRequestProperty("Content-Length", data.length()+"");//设置请求头,设置提交数据的长度
                                    //POST方式,实际是浏览器把数据写给了服务器
                                    uc.setDoOutput(true);//设置允许向外写数据
                                    uc.connect();//连接
                                    //4.通过getOutputStream()获得输出流往服务器写数据
                                    OutputStream outputStream = uc.getOutputStream();//通过getOutputStream()获得输出流
                                    outputStream.write(data.getBytes());
                                    int code = uc.getResponseCode();//获取HTTP状态码
                                    if (code == HttpURLConnection.HTTP_OK) {//5.得到响应码并判断连接正常后,通过getInputStream()方法获得携带服务器返回信息的输入流,从流中读取出服务器返回值,并向handler发送消息
                                        System.out.println(uc.getResponseCode());//控制台输出
                                        InputStream inputStream = uc.getInputStream();//得到响应流(通过getInputStream()方法获取携带服务器返回信息的输入流)
                                        int i = inputStream.read();
                                        System.out.println(i);//控制台显示是0还是1,以ASCII码形式显示
                                        //通过Message和handler.sendMessage()将返回结果传递给UI线程
                                        Message message = Message.obtain();//从服务器返回的数据,1.获取可用的Message对象
                                        message.arg1 =i;//2.通过message的arg1传递参数
                                        handler.sendMessage(message);//发送至主界面显示
                                    }else {
                                        System.out.println(uc.getResponseCode());//控制台输出
                                        Message message = Message.obtain();//从服务器返回的数据,1.获取可用的Message对象
                                        message.arg1 =2;//2.通过message的arg1传递参数
                                        handler.sendMessage(message);//发送至主界面显示
                                    }
                                }catch (Exception e) {
                                    e.printStackTrace();
                                }finally {
                                    if (uc != null) {
                                        uc.disconnect();//关闭HTTP连接
                                    }
                                }

五、做个实验

(一)实验效果如图所示

(二)实验步骤

MainActivity.java文件

1.在MainActivity.java中使用ConnectivityManager获取网络状态,完成网络状态判断方法checkNetworkState()的实现,具体步骤和代码在第一部分中已经给出

2.在 “登录”按钮的事件监听方法btnLogin.setOnClickListener()中,新建线程并使用HttpURLConnection访问服务器进行用户名和密码的验证,并将结果发送给Handler对象

重写run()方法中采用GET或POST方法提交数据,代码在第四部分已经给出

btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final String name=edName.getText().toString();
                final String pwd=edPwd.getText().toString();
                if(checkNetworkState()!=true){//判断是否联网
                    Toast.makeText(MainActivity.this,"网络没有打开,请打开网络后再试。",Toast.LENGTH_LONG).show();
                }else {

                    if (name.equals("")) {
                        Toast toast = Toast.makeText(MainActivity.this, "输入用户名", Toast.LENGTH_LONG);
                        toast.show();
                    }else if (pwd.equals("")) {
                        Toast toast = Toast.makeText(MainActivity.this, "输入密码", Toast.LENGTH_LONG);
                        toast.show();
                    }else {
                        //新建线程,并通过GET或post方式把用户名和密码向服务器发送请求并将结果发送给Handler对象
                        new Thread(new Runnable() {
                            @Override
                            public void run() {//重写run()方法
                            }
                        }).start();
                    }
                }
            }
        });

3.在onCreate()方法外部,实现Handler的handleMessage()方法,根据服务器返回结果判断是否登录成功

final Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            //通过msg中传递数据判断是否登录成功,若成功则实现界面跳转到WelcomeActivity
            int i = msg.arg1;
            if (i==49) {//界面跳转
                Intent intent = new Intent(MainActivity.this, WelcomeActivity.class);
                startActivity(intent);
            }else if (i==48) {//Toast提示用户名或密码错误
                Toast.makeText(MainActivity.this, "用户名或密码错误!", Toast.LENGTH_LONG).show();
            }else {//Toast提示连接失败
                Toast.makeText(MainActivity.this, "网络连接失败!", Toast.LENGTH_LONG).show();
            }
        }
    };

WelcomeActivity.java文件

4.完成DownloadTask类中各个方法的实现。doInBackground()方法中使用HttpURLConnection访问服务器并下载图片,下载过程中实时发布下载进度,下载完成后返回Bitmap对象

class DownloadTask extends AsyncTask<String, Integer, Bitmap> {//分别代表:执行后台任务传递的参数、更新的进度值的类型(都是整形) 、返回结果类型
        @Override
        protected void onPreExecute() {//UI组件初始化设置
            super.onPreExecute();
            textView.setVisibility(View.VISIBLE);
            progressBar.setVisibility(View.VISIBLE);
            progressBar.setProgress(0);//设置进度条初始值为0
        }
        @Override
        protected Bitmap doInBackground(String... strings) {
            URL url;
            HttpURLConnection urlConnection = null;
            Bitmap bitmap = null;
            pbValue=0;//初始值为0
            try {
                /*url = new URL(strings[0]);//在URL构造方法中传入要访问资源的路径*/
                url = new URL(urlStr);
                urlConnection = (HttpURLConnection) url.openConnection();//根据url发送一个http的请求
                urlConnection.setRequestMethod("GET");//设置GET请求方式
                urlConnection.setConnectTimeout(5000);//设置超时时间
                urlConnection.connect();//连接
                if(urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK  /*urlConnection.getResponseCode() == 200*/ ) {//得到响应码,判断连接是否正常
                    System.out.println(urlConnection.getResponseCode());//控制台输出
                    InputStream inputStream = urlConnection.getInputStream();//通过getInputStream()方法获得携带服务器返回信息的输入流
                    System.out.println(inputStream);//控制台显示是0还是1,以ASCII码形式显示
                    int maxSize = urlConnection.getContentLength();//通过urlConnection的getContentLength()获取下载图片的总大小
                    byte[] buffer = new byte[1024*8];
                    int len = -1;
                    int process =0;
                    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                    while((len = inputStream.read(buffer)) != -1) {//通过inputStream.read(buffer)和while循环读取数据,并通过ByteArrayOutputStream将数据写入
                        process += len;
                        byteArrayOutputStream.write(buffer, 0, len);
                        Thread.sleep(50);//每隔50ms通过publishProgress()发布进度值
                        pbValue = (int) ((((double)process)/maxSize)*progressBar.getMax());//计算数据下载的完成百分比
                        publishProgress(pbValue);//发布进度
                    }
                    /*byteArrayOutputStream.flush();*/
                    //数据读取完成后通过BitmapFactory.decodeByteArray()将ByteArrayOutputStream对象out中数据转换成Bitmap对象并返回
                    byte[] result = byteArrayOutputStream.toByteArray();
                    bitmap = BitmapFactory.decodeByteArray(result, 0, maxSize);
                    /*bitmap = BitmapFactory.decodeByteArray(byteArrayOutputStream.toByteArray(), 0, maxSize);*/
                }
            }catch (Exception e) {
                e.printStackTrace();
            }finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();//关闭HTTP连接
                }
                return bitmap;
            }
        }
        @Override
        protected void onProgressUpdate(Integer... values) {//下载过程中更新TextView和进度条的进度值
            super.onProgressUpdate(values);
            textView.setText("已下载"+ values[0]+"%");
            progressBar.setProgress(values[0]);
        }
        @Override
        protected void onPostExecute(Bitmap bitmap) {//下载完成后更新TextView和进度条
            super.onPostExecute(bitmap);
            Toast.makeText(WelcomeActivity.this, "加载完毕", Toast.LENGTH_SHORT).show();
            textView.setText("恭喜!下载完成!");
            progressBar.setVisibility(View.INVISIBLE);//下载完成后进度条消失
            imageView.setImageBitmap(bitmap);
        }
    }

5.在“下载图片”按钮的事件监听方法btnGetPic.setOnClickListener ()中,新建DownloadTask类的异步任务并调用execute(urlStr)方法执行网络图片的下载任务

btnGetPic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new DownloadTask().execute(urlStr);//创建DownloadTask实例对象,并调用其execute()方法
            }
        });

完整代码请从这里下载

注意事项:

1.我上传的压缩包中包含两个文件,TestServer要导入myeclipse中,HttpUrlExeStud导入Android Studio中

2.TestServer下存在一个Login文件,其中

if(name!=null && pass!=null && name.equals("JMX") && pass.equals("666"))

包含了我的用户名和密码,你可以进行更换,建议用户名设置为英文

3.TestServer必须运行起来,右击TestServer项目,点击Run As – 3 MyEclipse Server Application,弹出如下界面则表示成功

4.HttpUrlExeStud下MainActivity.java的GET、POST方法和WelcomeActivity.java分别包含这几行代码

String urlStr = "http://192.192.192.192:8080/TestServer/servlet/Login?name="+URLEncoder.encode(name)+"&pass="+URLEncoder.encode(pwd);
String urlStr = "http://192.192.192.192:8080/TestServer/servlet/Login";
final String urlStr="http://192.192.192.192:8080/TestServer/pic/bamboo1.jpg";

其中192.192.192.192是我的ip地址,实际运行时需要替换成你自己的ip地址。可以通过win+R,键入cmd,输入ipconfig的方式获取到计算机ip信息

到此这篇关于Android使用HttpURLConnection实现网络访问流程的文章就介绍到这了,更多相关Android HttpURLConnection内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android中HttpURLConnection类使用介绍

    Http协议的认识: Android中发送http网络请求是很常见的,要有GET请求和POST请求.一个完整的http请求需要经历两个过程:客户端发送请求到服务器,然后服务器将结果返回给客户端. GET表示希望从服务器那里获取数据,而POST则表示希望提交数据给服务器. 通过Http访问网络的三个步骤: 1.发送http请求 2.接受服务响应 3.解析返回数据 HttpURLConnection类位于java.net包中,它用于发送HTTP请求和获取HTTP响应. 话不多说,直接上代码: 首先创

  • Android 用HttpURLConnection访问网络的方法

    一. HttpURLConnection以GET方式访问网络: HttpURLConnection connection = null; try { URL url = new URL("https://www.xxx.com/"); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET");//设置访问方式为"GET" co

  • Android开发使用HttpURLConnection进行网络编程详解【附源码下载】

    本文实例讲述了Android开发使用HttpURLConnection进行网络编程.分享给大家供大家参考,具体如下: --HttpURLConnection URLConnection已经可以非常方便地与指定站点交换信息,URLConnection下还有一个子类:HttpURLConnection,HttpURLConnection在URLConnection的基础上进行改进,增加了一些用于操作HTTP资源的便捷方法. setRequestMethod(String):设置发送请求的方法 get

  • 创建子线程对Android进行网络访问

    //主线程中接收子线程发送的消息并处理 private Handler handler=new Handler(){ @SuppressLint("HandlerLeak") public void handleMessage(Message msg){ try { switch (msg.what){ case 0: String Listeningresponse= msg.getData().getString("Listeningdate"); case 1

  • Golang+Android基于HttpURLConnection实现的文件上传功能示例

    本文实例讲述了Golang+Android基于HttpURLConnection实现的文件上传功能.分享给大家供大家参考,具体如下: 这里要演示的是使用Android程序作为客户端(使用HttpURLConnection访问网络),Golang程序作为服务器端,实现文件上传. 客户端代码: public static String uploadFile(String uploadUrl, String filePath) { Log.v(TAG, "url:" + uploadUrl)

  • Android编写简单的网络爬虫

    一.网络爬虫的基本知识 网络爬虫通过遍历互联网络,把网络中的相关网页全部抓取过来,这体现了爬的概念.爬虫如何遍历网络呢,互联网可以看做是一张大图,每个页面看做其中的一个节点,页面的连接看做是有向边.图的遍历方式分为宽度遍历和深度遍历,但是深度遍历可能会在深度上过深的遍历或者陷入黑洞.所以,大多数爬虫不采用这种形式.另一方面,爬虫在按照宽度优先遍历的方式时候,会给待遍历的网页赋予一定优先级,这种叫做带偏好的遍历. 实际的爬虫是从一系列的种子链接开始.种子链接是起始节点,种子页面的超链接指向的页面是

  • Android中ImageView使用网络图片资源的方法

    本文实例讲述了Android中ImageView使用网络图片资源的方法.分享给大家供大家参考.具体如下: 很多时候我们不想把东西都放在APK里面,或者是不能放进去,这时候我们就需要万能的网路帮助自己实现了 运行效果截图如下: java代码如下: package com.android.antking.imageview; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.Malformed

  • Android通过ConnectivityManager检查网络状态

    在开发android应用时,涉及到要进行网络访问,时常需要进行网络状态的检查,以提供给用户必要的提醒.一般可以通过ConnectivityManager来完成该工作. ConnectivityManager有四个主要任务: 1.监听手机网络状态(包括GPRS,WIFI, UMTS等) 2.手机状态发生改变时,发送广播 3.当一个网络连接失败时进行故障切换 4.为应用程序提供可以获取可用网络的高精度和粗糙的状态当我们要在程序中监听网络状态时,只要一下几个步骤即可: 1.定义一个Receiver重载

  • Android编程简单获取网络上的图片

    本文实例讲述了Android编程简单获取网络上的图片的方法.分享给大家供大家参考,具体如下: 要获取网络上的图片,首先得有网络的访问权限,这个不再写了,以前的文章中写过,还有布局方式不再写了,就是写也是一个简单的布局,没有多大意义,直接上核心代码: 这是本人使用的一个简单的类,来获取网上的图片. public static Bitmap getImage(String Url) throws Exception { try { URL url = new URL(Url); String res

  • Android自定义短信倒计时view流程分析

    倒计时实现有三种方式 而这个自定义view是通过handler实现的.为了保证activity销毁的同时倒计时线程依然进行同时重新创建销毁又不会导致内存泄漏,我使用了handler的弱引用将handler和runnable设置成静态,同时通过一系列变量来销毁关闭线程保存状态,话不多说先看效果图: 下面看源码: import android.content.Context; import android.os.Handler; import android.os.Message; import a

  • Android 实例开发一个学生管理系统流程详解

    目录 效果演示 实现功能总览 代码 登录与忘记密码界面 一.添加布局文件 二.添加标题文字 三.绑定适配器 注册界面 一.创建两个Drawable文件 二.将其添加数组内 三.动态变化背景 考勤界面 一.CircleProgressBar代码如下 签到界面 一.倒计时 二.位置签到 成绩查询界面 一.创建StackAdapter 适配器 效果演示 随手做的一个小玩意,还有很多功能没有完善,倘有疏漏,万望海涵. 实现功能总览 实现了登录.注册.忘记密码.成绩查询.考勤情况.课表查看.提交作业.课程

随机推荐