Android使用HttpURLConnection访问网络

一、管理网络状态

使用网络进行数据通信前,需要先获取网络状态。
使用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.判断当前网络状态是否为连接状态,如果当前没有网络是活动的,则返回nullreturn 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"/><!--增加访问网络授权声明--><applicationandroid: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() {@Overridepublic 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() {@Overridepublic void run() {//重写run()方法}}).start();}}}});

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

final Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {//通过msg中传递数据判断是否登录成功,若成功则实现界面跳转到WelcomeActivityint 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> {//分别代表:执行后台任务传递的参数、更新的进度值的类型(都是整形) 、返回结果类型@Overrideprotected void onPreExecute() {//UI组件初始化设置super.onPreExecute();textView.setVisibility(View.VISIBLE);progressBar.setVisibility(View.VISIBLE);progressBar.setProgress(0);//设置进度条初始值为0}@Overrideprotected Bitmap doInBackground(String... strings) {URL url;HttpURLConnection urlConnection = null;Bitmap bitmap = null;pbValue=0;//初始值为0try {/*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;}}@Overrideprotected void onProgressUpdate(Integer... values) {//下载过程中更新TextView和进度条的进度值super.onProgressUpdate(values);textView.setText("已下载"+ values[0]+"%");progressBar.setProgress(values[0]);}@Overrideprotected 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() {@Overridepublic void onClick(View v) {new DownloadTask().execute(urlStr);//创建DownloadTask实例对象,并调用其execute()方法}});

完整代码请从这里下载https://download.csdn.net/download/m0_66309026/85042039
注意事项:
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访问网络相关推荐

  1. android访问网络的方法,Android Http协议访问网络实例(3种)

    之前关于Android Http协议访问网络的一点分析,最近需要回顾,就顺便发到随笔上了 Android中http连接主要是为了获取网络数据,目前了解的有3种方法: Httpconnection -- ...

  2. 解决android模拟器不能访问网络的问题

    解决android模拟器不能访问网络的问题 参考文章: (1)解决android模拟器不能访问网络的问题 (2)https://www.cnblogs.com/oriental/p/11750330. ...

  3. 10_Android中通过HttpUrlConnection访问网络,Handler和多线程使用,读取网络html代码并显示在界面上,ScrollView组件的使用

     编写如下项目: 2 编写Android清单文件 <?xml version="1.0" encoding="utf-8"?> <mani ...

  4. Android使用Http访问网络

    Android6.0(API23)系统之后,Android上发送HTTP请求的方式只有一种HttpUrlConnection 基本用法:通过一个执行路径的URL,获取到HttpUrlConnectio ...

  5. android主线程访问网络的方法

    从两个方面说下这个问题: 1. 不让访问网络的原因 2. 解决该问题的办法 不让访问网络的原因: 由于对于网络状况的不可预见性,很有可能在网络访问的时候造成阻塞,那么这样一来我们的主线程UI线程 就会 ...

  6. Android 使用 HTTP 访问网络

    使用 HttpURLConnection 在过去,Android 上发送 HTTP 请求一般有两种方式:HttpURLConnection 和 HttpClient,不过在 Android 6.0 系 ...

  7. Android学习:访问网络

    1.Get请求和Post请求简介 当客户端与服务器建立了网络链接之后,就可以发送Http请求了.Http请求通常分为Get请求和Post请求两种,下面分别介绍: 1.Get请求 Get:通过请求URI ...

  8. Android多媒体学习六:访问网络上的Audio对应的M3U文件,实现网络音频流的播放

    Android中提供了对网络上流媒体的支持,我们可以使用MediaPlayer类来播放一个网络上的音频文件. 但是网络上的站点并不建议我们直接访问流,我们需要获取他提供的M3U文件,根据M3U文件来实 ...

  9. HttpURLConnection, Android访问网络,实用demo

    常量 private static final String CHARSET = "UTF-8"; private static final String HTTP_METHOD_ ...

最新文章

  1. OpenCV 多层感知器训练代码示例
  2. java菜单栏的功能怎么被关闭_【求助帖】 菜单栏的监听问题
  3. docker快速入门01——docker安装与简单应用
  4. Python模块——_winreg操作注册表
  5. ue4集合类型_UE4粒子系统渲染管线概述
  6. React Native顶|底部导航使用小技巧
  7. Extended Twin Composite Number 思维题
  8. 拥抱开源未来 百度Doris进入顶级开源社区Apache
  9. Linux实验——缓冲区溢出漏洞实验
  10. CRLF对GIT DIFF的影响
  11. 李宏毅机器学习——逻辑回归
  12. .Net_asp.net页面的生命周期
  13. 你的计算机无法启动一键还原,电脑一开机就进入dos之家的一键还原硬盘版,无法进入系统...
  14. WINCE环境下 helloWorld
  15. python画圆形螺旋线_在PDMS中使用python直接生成管口方位图(开源分享第三集)...
  16. 软件测试中的人工智能现状:未来会怎样?
  17. 洛必达法则的一种极简证明
  18. 2019 年度程序员薪酬报告:40 岁以后普遍遭遇收入天花板
  19. VBA中Sheets(String)和Sheets(Long)的速度
  20. 正则表达式与遇到的问题

热门文章

  1. 超级详细树讲解三 —— B树、B+树图解+代码
  2. markdown语法教学(for萌新版)
  3. 高学历就意味着高薪资?低学历转行3D建模,游戏建模成为首选
  4. Js如何实现收藏功能
  5. 计算机操作系统相关论文,计算机操作系统的基本功能及应用论文
  6. Zoom WebTeam面经
  7. 联想y430完全拆机图解_Y430P拆机:安装内存+清灰
  8. r5处理器_Intel难受了,R54500U,6核心处理器笔记本价格才3499元
  9. 树上战争(2545)
  10. 修改ttf字体美化显示效果