1.介绍

总结:HttpURLConnection用来发送和接收数据。

2.ANR异常报错

(1)ANR(Application not response) 应用无响应, 主线程(UI线程)

(2)如果在主线程中进行耗时操作(比如连接网络、拷贝大量的数据),都会报ANR异常

(3)避免ANR报错,可以把耗时操作放到子线程中,自己再创建一个线程。

(4)android 4.0之后,Google公司要求连接网络不能在主线程中进行访问。

总结:主线程中不要执行耗时操作(比如连接网络、拷贝大量的数据、Thread.sleep()),应在子线程中操作。

UI的更新应该在主线程中执行。

3.handler原理

handler是更新UI界面的机制,也是消息处理的机制,我们可以发送消息,也可以处理消息

handler实现主线程与子线程之间的交互。

handler使用步骤:

(1)在主线程定义一个handler

(2)重写handler的handleMessage()方法

(3)在子线程中发送需要设置的消息内容

(4)handler中进行接收消息,并设置ui

注意:

<1>hander的作用是发送并处理消息

<2>子线程最好不要更新ui组件

<3>Looper的作用是监视消息队列,若消息队列中有消息,则取出消息并将消息交给hander处理。

Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
//在主线程里更新ui
String strTemp= (String) msg.obj;
tv_websiteShow.setText(strTemp);
}
};

4.网址测试时,网址最好复制网上的直接网址,不要自己手动输入。

5.使用技巧(避免出错):

<1>无论哪个版本的手机,只要涉及耗时操作(比如连接网络,拷贝大量的数据等),则需要开辟一个子线程

<2>获取数据后想要更新ui,就使用Handler就可以了

6.利用手机的缓存功能

//缓存图片(节省流量)
FileOutputStream fos=new FileOutputStream(file); //创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
int len=-1;
byte[] buffer=new byte[1024]; //1kb
while ((len=in.read(buffer))!=-1){ //从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
fos.write(buffer,0,len);
}
fos.close();
in.close();

7.java代码

<1>MainActivity.class

注意:更新ui组件有两种方法:(1)利用handler发送消息,修改ui组件(必须掌握,万能) (2)调用runOnUiThread()方法,实现在子线程中更新ui的效果。(有的情况下不能使用)

package com.example.lucky.test54wanzhichakan;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast; import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL; public class MainActivity extends AppCompatActivity {
protected static final int REQUESTSUCCESS=0;
protected static final int REQUESTNOTFOUND=1;
protected static final int REQUESTEXCEPTION=2;
protected static final int REQUESTIMAGESUCCESS=3;
Button bt_showText;
Button bt_showImage;
TextView tv_websiteShow;
EditText et_website;
ImageView iv_pic1;
@SuppressLint("HandlerLeak")
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case REQUESTSUCCESS: //请求成功
//在主线程里更新ui
String strTemp= (String) msg.obj;
tv_websiteShow.setText(strTemp);
break;
case REQUESTNOTFOUND:
Toast.makeText(MainActivity.this,"请求未响应",Toast.LENGTH_LONG).show();
break;
case REQUESTEXCEPTION:
Toast.makeText(MainActivity.this,"服务器正忙,稍后再试",Toast.LENGTH_LONG).show();
break;
case REQUESTIMAGESUCCESS:
Bitmap bitmap= (Bitmap) msg.obj;
iv_pic1.setImageBitmap(bitmap);
break;
} }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_showText=findViewById(R.id.bt_showText);
bt_showImage=findViewById(R.id.bt_showImage);
tv_websiteShow=findViewById(R.id.tv_websiteShow);
et_website=findViewById(R.id.et_website);
iv_pic1=findViewById(R.id.iv_pic1);
bt_showText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
          //开启一个子线程
new Thread(){
@Override
public void run() {
String website=et_website.getText().toString().trim(); //trim()方法用于去除字符串开头和结尾的空白
try {
//1.创建URL,指定我们要访问的网址
URL url=new URL(website);
//2.获取HttpURLConnection对象,用于发送或接收数据
HttpURLConnection conn= (HttpURLConnection) url.openConnection();
System.out.println("-------------------flaglucky");
//3.设置请求格式为get
conn.setRequestMethod("GET"); //注意get要求大写,默认为get请求
//4.设置请求的超时时间
conn.setConnectTimeout(5000);
//5.获取服务器返回的状态码
int code=conn.getResponseCode();
System.out.println("--------------"+code);
//如果code==200说明请求成功
if(code==200){
System.out.println("-------------------flagif");
//6.获取服务器返回的数据(以流的形式返回)
InputStream in=conn.getInputStream();
//7.用定义的工具类将InputStream类型的数据转换为String
String contentStr=StreamTools.readStream(in); //8.1创建message对象
Message msg=new Message();
msg.obj=contentStr; //设置消息内容
msg.what=REQUESTSUCCESS; //设置消息代号
handler.sendMessage(msg); //利用handler告诉系统需要更新ui组件,则handlermessage方法就会执行
}else {
Message msg=new Message();
msg.what=REQUESTNOTFOUND;
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
Message msg=new Message();
msg.what=REQUESTEXCEPTION;
handler.sendMessage(msg);
}
}
}.start(); }
});
bt_showImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//开启一个子线程
new Thread(){
@Override
public void run() {
try {
File file=new File(getCacheDir(),"test.png");
//判断图片是否已经缓存
if(file.exists()&&file.length()>0){
System.out.println("使用缓存图片");
//7.利用BitmapFactory将InputStream类型的数据转换为Bitmap
Bitmap bitmap=BitmapFactory.decodeFile(file.getAbsolutePath()); //8.1创建message对象
Message msg=new Message();
msg.obj=bitmap; //设置消息内容
msg.what=REQUESTIMAGESUCCESS; //设置消息代号
handler.sendMessage(msg); //利用handler告诉系统需要更新ui组件,则handlermessage方法就会执行
}else {
System.out.println("第一次连接网络");
String picPath=et_website.getText().toString().trim();
//1.创建URL,指定我们要访问的网址
URL url=new URL(picPath);
//2.获取HttpURLConnection对象,用于发送或接收数据
HttpURLConnection conn= (HttpURLConnection) url.openConnection();
System.out.println("-------------------flaglucky");
//3.设置请求格式为get
conn.setRequestMethod("GET"); //注意get要求大写,默认为get请求
//4.设置请求的超时时间
conn.setConnectTimeout(5000);
//5.获取服务器返回的状态码
int code=conn.getResponseCode();
System.out.println("--------------"+code);
//如果code==200说明请求成功
if(code==200){
System.out.println("-------------------flagif");
//6.获取服务器返回的数据(以流的形式返回)
InputStream in=conn.getInputStream();
//缓存图片(节省流量)
FileOutputStream fos=new FileOutputStream(file); //创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
int len=-1;
byte[] buffer=new byte[1024]; //1kb
while ((len=in.read(buffer))!=-1){ //从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
fos.write(buffer,0,len);
}
fos.close();
in.close();
//7.利用BitmapFactory将InputStream类型的数据转换为Bitmap
final Bitmap bitmap=BitmapFactory.decodeFile(file.getAbsolutePath()); // //8.1创建message对象
// Message msg=new Message();
// msg.obj=bitmap; //设置消息内容
// msg.what=REQUESTIMAGESUCCESS; //设置消息代号
// handler.sendMessage(msg); //利用handler告诉系统需要更新ui组件,则handlermessage方法就会执行 //使用runOnUiThread()方法相当于在主线程中执行run()方法
runOnUiThread(new Runnable() {
@Override
public void run() {
iv_pic1.setImageBitmap(bitmap);
}
});
}else {
Message msg=new Message();
msg.what=REQUESTNOTFOUND;
handler.sendMessage(msg);
}
}
} catch (Exception e) {
e.printStackTrace();
Message msg=new Message();
msg.what=REQUESTEXCEPTION;
handler.sendMessage(msg);
}
}
}.start();
}
});
}
}

<2>工具类

package com.example.lucky.test54wanzhichakan;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream; //流操作的工具类
public class StreamTools {
//把一个inputStream转换为String
public static String readStream(InputStream in) throws Exception {
//定义一个内存输出流
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int len=-1;
byte[] buffer=new byte[1024];//大小为1kb
while ((len=in.read(buffer))!=-1){ //read()方法:从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中,若到文件结尾返回-1
baos.write(buffer,0,len);
}
in.close(); //关闭流
String content=new String(baos.toByteArray());
return content;
}
}

7.效果图

Android HttpURLConnection的使用+Handler的原理及典型应用的更多相关文章

  1. android handler工作原理

    android handler工作原理 作用 便于在子线程中更新主UI线程中的控件 这里涉及到了UI主线程和子线程 UI主线程 它很特别.通常我们会认为UI主线程将页面绘制完成,就结束了.但是它没有. ...

  2. android高级---->Handler的原理

    andriod提供了Handler来满足线程间的通信,上次在更新UI的时候也提到过Handler的使用,关于Handler的基本使用,参见博客(android基础---->子线程更新UI).今天 ...

  3. android基础---->DiskLruCache的使用及原理

    DiskLruCache是谷歌推荐的用来实现硬盘缓存的类,今天我们开始对于DiskLruCache的学习.DiskLruCache的测试代码:DiskLruCache的测试代码下载.关于FidkLru ...

  4. Android HttpURLConnection源代码分析

    Android HttpURLConnection源代码分析 之前写过HttpURLConnection与HttpClient的差别及选择.后来又分析了Volley的源代码. 近期又遇到了问题,想在V ...

  5. Android之——AsyncTask和Handler对照

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46952835 AsyncTask和Handler对照 1 ) AsyncTask实 ...

  6. 知乎1578赞:Android 中为什么需要 Handler?

    要理解 Handler,就得先理解 Android 的 Message 机制. 这里以用户滑动微信朋友圈为例,讲解一下 Android 的 Message 机制是怎么运行的,Message 机制中的各 ...

  7. Android源码解析——Handler、Looper与MessageQueue

    本文的目的是来分析下 Android 系统中以 Handler.Looper.MessageQueue 组成的异步消息处理机制,通过源码来了解整个消息处理流程的走向以及相关三者之间的关系 需要先了解以 ...

  8. Android开发 之 理解Handler、Looper、MessageQueue、Thread关系

    本文转自博客:http://blog.csdn.net/he90227/article/details/43567073 一. 图解与概述 首先Android中 的每一个线程都会对应一个Message ...

  9. 【Android 开发】: Android 消息处理机制之一: Handler 与 Message

    最近几讲内容,我们学习了Android中关于多线程的一些知识,上一讲我们讲解了异步任务 AsyncTask 的操作,Android中还提供了其他的线程操作,如Handler Message Messa ...

随机推荐

  1. 【bzoj1018】[SHOI2008]堵塞的交通traffic

    1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 2887  Solved: 954[Submit ...

  2. JS 实现 unicode 中文互转

    // 转为unicode 编码 function encodeUnicode(str) { var res = []; for ( var i=0; i<str.length; i++ ) { ...

  3. Linux awk&sed

    awk AWK是强大的文本处理工具,擅长对日志文件迚行快速分析. 它丌仅用亍 Linux ,也是任何环境中现有的功能最强大的数据处理引擎之一. 名称得自亍它的发明者 Alfred Aho .Pet ...

  4. Python父类调用子类

    首先说明,上面的标题其实是不正确的,Python是一门解释型.动态数据类型的高级语言,运行时,动态判断调用对象,其实还是子类自己在调用自己的方法或属性. 举个例子(copy过来的):SocketSer ...

  5. 367. Valid Perfect Square判断是不是完全平方数

    [抄题]: Given a positive integer num, write a function which returns True if num is a perfect square e ...

  6. 安装 SQL Server 2014 Express

    安装 SQL Server 2014 Express 我的电脑系统: Windows 10 64位 一 . 下载 安装Microsoft SQL Server 2014 Express 软甲下载地址: ...

  7. vuex 数据绑定

    操作文档: 安装vuex: cnpm install vuex --save   文档介绍: https://vuex.vuejs.org/guide/modules.html   import Vu ...

  8. js-修改url中某个指定的参数的值

    /* * url 目标url * arg 需要替换的参数名称 * arg_val 替换后的参数的值 * return url 参数替换后的url */ function changeURLArg(ur ...

  9. Java 扫描器类 Scanner类

    1.Scanner是SDK1.5新增的一个类,可是使用该类创建一个对象.Scanner reader=new Scanner(System.in); 2.reader对象调用下列方法(函数),读取用户 ...

  10. 20169219 SQL注入实验报告

    实验介绍 SQL注入技术是利用web应用程序和数据库服务器之间的接口来篡改网站内容的攻击技术.通过把SQL命令插入到Web表单提交框.输入域名框或页面请求框中,最终欺骗服务器执行恶意的SQL命令. 在 ...