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. MySql 获取服务提供的sakila数据库(Example Databases)

    关于这个数据库也就是样例数据库,数据库,数据库,最可怕的就是没有数据了,对吧?没有数据你学个什么呀. 可是,没有数据,咱会自己insert,那只能适用于初学者.对于数据库的优化方面的学习,还是有大数据 ...

  2. Solidity 没名字的function(){...}作用

    官方解释: 这个叫做fallback function,当有人 1. 只发送以太币给合约而不带任何输入数据:2. 调用smart contract时调起了一个不存在的方法.会触发执行这个方法. Wha ...

  3. Django--form验证及错误处理

    需求 from表单验证和ajax验证时返回的错误信息处理 速查 1.form表单提交时错误信息显示 views 1 2 error = form表单实例化对象.errors return render ...

  4. 500 Internal Server Error

    解决策略: 1.httpd.conf中,开启apache头信息自定义模块 2.htaccess文件,对这个域名的资源进行访问时,添加一个头信息 Header set Access-Control-Al ...

  5. c# 二分查找法(2分钟算法)

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  6. Entity Framework Tutorial Basics(43):Download Sample Project

    Download Sample Project: Download sample project for basic Entity Framework tutorials. Sample projec ...

  7. input file 获取不到Request.Files 解决办法

    <input type="file" name="xxxxxxx"/>必须有“name”属性,否则在后台代码中用Request.Files是取不到值 ...

  8. Visual Studio 2010调试本地 IIS 站点

    点击vs的Debug-Attach to Process选中 w3wp.exe,然后点击Attach, vs便进入debug模式.

  9. python23种设计模式

      第一篇 Python与设计模式:前言 第二篇(23种设计模式) 创建类设计模式(5种) 单例模式.工厂模式.简单工厂模式.抽象工厂模式.建造者模式.原型模式 结构类设计模式(7种) 代理模式.装饰 ...

  10. C#获取文件的Content-Type(MIME Type)的方法

    使用静态类MimeMapping(需要.NET Framework 4.5及以后的支持) string fileName = "D:\myfile.txt"; var conten ...