一、HTTP
HTTP:”超文本传输协议”,是互联网上应用最为广泛的一种网络协议,用于实现互联网中WWW服务,大多数网站都是使用HTTP协议访问的。
HTTP请求
- HTTP请求是客户端和服务器端之间,发送请求和返回应答的标准(TCP)。
- 客户端发出一个HTTP请求后,就与服务器建立起了TCP连接,服务端接收到请求并进行处理后返回给客户端响应数据。
HTTP常用的请求方式
- get方式属于明文传参,在地址栏可以看到参数,调用简单,不安全。
- post方式输入暗文传参,在地址栏参数不可见,调用稍复杂,安全。
二、HttpURLConnection
HttpURLConnection是URLConnection的子类,每个HttpURLConnection 实例都可用于生成单个请求,HttpURLConnection是基于http协议的,支持get,post,put,delete等各种请求方式,最常用的就是get和post。
HttpURLConnection的常用方法
- openConnection():获得HttpURLConnection对象
- setConnectTimeout(int timeout):设置一个指定的链接超时时间(以毫秒为单位)
- setResquestMethod(String method):设置请求方式
- getOutputStream():服务器建立连接,得到输出流对象
- getInputStream():发送报文,得到服务器返回的输入流
getResponseCode():从HTTP响应消息获取状态码
使用HttpURLConnection发送GET请求的步骤
- 创建URL对象
- 通过URL对象调用openConnection()方法获得HttpURLConnection对象
- HttpURLConnection对象设置其他连接属性
- HttpURLConnection对象调用getInputStream()方法向服务器发送http请求并获取到服务器返回的输入流
- 读取输入流,转换成String字符串
注意:
1、在Android中访问网络必须添加网络权限
2、在Android中访问网络必须放在子线程中执行
运用HttpURLConnection发送获取csdn网站的请求
代码如下:
在xml文件中建立一个按钮控件,使点击后访问csdn网站
<Button
android:id="@+id/web_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Activity中代码
public class Main4Activity extends AppCompatActivity {
private Button webBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
webBtn=findViewById(R.id.web_btn);//绑定ID
//设置监听事件
webBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread(new Runnable() {
@Override
public void run() {
getWebInfo();
}
});
}
});
}
private void getWebInfo() {
try {
//创建URL对象,并添加所要访问的对象
URL url = new URL("https://www.youkuaiyun.com/");
//得到HttpURLConnection 中对象
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
//创建输入流
InputStream inputStream=httpURLConnection.getInputStream();
//创建输入流读取对象
InputStreamReader reader = new InputStreamReader(inputStream, "UTF-8");
//输入流缓存读取
BufferedReader bufferedReader=new BufferedReader(reader);
StringBuffer stringBuffer=new StringBuffer();
String temp=null;
//输入流转换成String
while ((temp=bufferedReader.readLine())!=null){
stringBuffer.append(temp);
}
bufferedReader.close();
reader.close();
inputStream.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用HttpURLConnection加载网络图片
使用HttpURLConnection加载网络图片就需要使用Bitmap,Bitmap的加载离不开BitmapFactory类,而BitmapFactory类提供了四类方法用来加载Bitmap,这次我们需要用到decodeStream 方法。
decodeStream 方法:
1.开启异步线程去获取网络图片
2.网络返回InputStream
此次我们用AsyncTask方法来加载界面
Activiyy代码如下:
public class Main5Activity extends AppCompatActivity {
private Button webBtn;
private ImageView webImg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main5);
bindID();
webBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//初始化MyTask 类,MyTask 类是辅助Activity类完成网络加载
MyTask myTask=new MyTask(webImg);
//启动异步任务,execute中存放的是所要加载的图片的地址
myTask.execute("http://f.hiphotos.baidu.com/zhidao/pic/item/faedab64034f78f0323184f57f310a55b3191cf9.jpg");
}
});
}
private void bindID() {
webBtn=findViewById(R.id.webtu_btn);
webImg=findViewById(R.id.web_img);
}
}
MyTask 类代码:
//根据不同类型写入不同参数
public class MyTask extends AsyncTask<String,Integer,Bitmap>{
//定义全局Bitmap对象
private Bitmap bitmap=null;
private ImageView imageView;
//运用构造方法来向Activity传值
public MyTask(ImageView imageView){
this.imageView=imageView;
}
@Override
protected Bitmap doInBackground(String... strings) {
try {
//创建URL对象,获得Activity中的传值
URL url=new URL(strings[0]);
//获取HttpURLConnection对象
HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();
//向服务器发送http请求并获取到服务器返回的输入流
InputStream inputStream=httpURLConnection.getInputStream();
//读取输入流,转换成String字符串
//运用BitmapFactory.decodeStream方法开启异步线程去获取网络图片,返回InputStream
bitmap= BitmapFactory.decodeStream(inputStream);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;//返回bitmap获得的传值
}
@Override
protected void onPostExecute(Bitmap integer) {//Bitmap所对应的参数是AsyncTask中第三个参数
super.onPostExecute(integer);
imageView.setImageBitmap(integer);
}
}
注意:使用HttpURLConnection加载网络图片时会出现权限问题
在AndroidManifest中添加代码
<uses-permission android:name="android.permission.INTERNET" />
使用HttpURLConnection下载网络资源并读取本地资源
用下载网络图片为例
运用AsyncTask为例,先是创建一个辅助类继承AsyncTask,代码如下:
public class DownLodaTask extends AsyncTask<String,Integer,Integer> {
private String Filename;
private ImageView imageView;//定义所下载的图片
private Button downloadBtn;
private String SDpath="";//定义下载的路径目录
private String path="";//定义最终下载地点
private Context context;//全局定义Context ,联系上下文
//运用构造方法联系上下文
public DownLodaTask(ImageView imageView,Context context,Button downloadBtn){
this.context=context;
this.imageView=imageView;
this.downloadBtn=downloadBtn;
this.SDpath = Environment.getExternalStorageDirectory() + "/";
this.path=this.SDpath+"download_pic/";
}
@Override
protected Integer doInBackground(String... strings) {
//定义输入流和输出流
InputStream inputStream=null;
OutputStream outputStream=null;
//定义文件对象
File file = null;
Filename=path+strings[1];
//判断文件是否存在
if (isFileExists(Filename)) {
//如果存在,直接返回,执行onPostExecute方法
return -1;
}
try {
URL url=new URL(strings[0]);
HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection();
//判断网络是否异常,,若不等于200直接返回
if (httpURLConnection.getResponseCode()==200){
inputStream=httpURLConnection.getInputStream();
}else {
return -2;
}
//创建目录
createDir(path);
//创建文件
file = createFile(path+strings[1]);
//创建输出流
outputStream = new FileOutputStream(file);
//创建缓冲区
byte buffer[] = new byte[4*1024];//定义4kb大小
int length = 0;
//运用while循环语句判断是否输出完
while((length = inputStream.read(buffer))!=-1){
outputStream.write(buffer,0,length);
}
outputStream.flush();//强制把缓冲区的数据写入到文件并清空缓冲区
//关闭输入和输出流
outputStream.close();
inputStream.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return 1;
}
/**
* 工具方法——判断文件已存在
*
* @return
*/
private boolean isFileExists(String sDpath) {
File file = new File(sDpath);
if (file.exists()) {
// 文件已存在
return true;
}
return false;
}
/**
* 工具方法——创建目录
*/
private boolean createDir(String dirName) {
File file = new File(dirName);
boolean isCreateDir = file.mkdir();
return isCreateDir;
}
/**
* 工具方法——创建文件
* @param
*/
private File createFile(String fileName) {
File file = new File(fileName);
boolean isCreateFile = false;
try {
isCreateFile = file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
switch (integer){
case -1:
Toast.makeText(context,"文件已存在",Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(context,"下载完成",Toast.LENGTH_SHORT).show();
// 通过BitmapFactory.decodeFile方法获取下载的图片
Bitmap bt= BitmapFactory.decodeFile(Filename);
imageView.setImageBitmap(bt);
break;
break;
case -2:
Toast.makeText(context,"网络异常",Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
Activity中代码:
bindID();
downBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.web_downbtn:
//获取DownLodaTask类中传来的信息
DownLodaTask downLodaTask=new DownLodaTask(downImg,Main6Activity.this,downBtn);
//启动异步任务,第一个参数是图片的地址,第二个是所起的图片的名字
downLodaTask.execute("http://f.hiphotos.baidu.com/zhidao/pic/item/faedab64034f78f0323184f57f310a55b3191cf9.jpg","wease.jpg");
break;
}
}
});
在这里若想将本地内的文件提取出来就需要访问权限了,Android6.0以下版本只需要静态权限就可以
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 在sdcard中创建/删除文件的权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
而Android6.0以上版本的设备就需要添加动态权限,需要的朋友可以去下面博客获取
http://blog.youkuaiyun.com/jasper_success/article/details/78836899