HttpUrlConnection介绍:网页展示和图片下载。
Android项目演示
具体流程
通过HttpURLConnection访问百度网址,然后显示在客户端的WebView上面。
步骤解析
1)、设置xml文件,添加一个Webview控件和一个ImageView控件。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<WebView
<!-- android:visibility="gone"在使用图片下载功能的时候激活这行代码,使得WebView隐藏。 -->
android:id="@+id/webView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</WebView>
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
2)、在MainActivity中初始化Webview。同时设置setContentView(R.layout.activity_main);
关联xml布局文件。
3)、创建一个名为HttpThread的类继承Thread类,在这个类里面设置线程,完成相关的网络操作,因为网络操作都是十分耗时的,所以在子线程中进行网络操作。
代码分析:
*MainActivity.java*
package com.example.http_01;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.webkit.WebView;
import android.widget.ImageView;
//使用Android进行网页保存和网络图片的储存,主要是使用Thread线程来实现,
//对网络数据的操作主要是在这个线程类里面来进行。
//要记得在Manifest里面设置APP权限
//设置一个INTERNET网络访问权限,否则APP是无法访问网络的。
//<uses-permission android:name="android.permission.INTERNET"/>
//设置一个将信息保存在外置SD卡上的权限。
//<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
public class MainActivity extends Activity {
private WebView webview;
private Handler handler = new Handler();
private ImageView imageViwe;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webview = (WebView) findViewById(R.id.webView1);
imageViwe = (ImageView) findViewById(R.id.imageView1);
//记得调用HttpThread的start()方法,否则不能创建线程。
/*"http://img.zcool.cn/community/05fc19554ace1a00000115a89c9942.jpg"是图片网址,返回百度首页时设置为http://www.baidu.com.com*/
new HttpThread("http://img.zcool.cn/community/05fc19554ace1a00000115a89c9942.jpg",imageViwe, handler).start();
}
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
HttpThread.java
package com.example.http_01;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.xml.sax.InputSource;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.Handler;
import android.webkit.WebView;
import android.widget.ImageView;
//在Thread了日里面对网络资源进行操作的步骤可以总结如下(下图片的情况):
//1.初始话要用到的控件和类新建run方法。
//2.在run方法里面新建一个httpUrl来保存又构造方法传进来的url。
//3.利用这个httpUrl的openConnection方法来建立一个HttpURLConnection对象conn。
//conn可以完成单个请求,使用这个请求可以完成“访问方式”、“等待的时间”的设置。
//4.利用conn的getInputStream方法设置一个InputStream输入流对象in。来传递网络数据。
//5.因为要存档,所以还要新建文件位置。
//6.将信息先写进缓存区b里面,在把b里的信息转存到out这个位置,使用的是decodeFile方法
//将下载了的文件(downloadFlie)在本地进行解析,转化成bitmap。
//7.设置handler.post方法,回传给主线程。setImageView为bitmap,展示出来。
public class HttpThread extends Thread {
//url是统一资源定位符的缩写,用来定位网络上唯一存在的网址信息
private String url;
private WebView webview;
//因为我们要在子线程里面更新url,所以我们在这里创建一个handler;Handler主要用于异步消息的处理
//在Android中,对于UI的操作通常需要放在主线程中进行操作。如果在子线程中有关于UI的操作,
//那么就需要把数据消息作为一个Message对象发送到消息队列中,
//然后,由Handler中的handlerMessage方法处理传过来的数据信息,并操作UI。
private Handler handler;
private ImageView imageview;
//这是这个HttpThread类的构造方法。
public HttpThread(String url,ImageView imageview,Handler handler){
this.url = url;
this.imageview = imageview;
this.handler = handler;
}
//因为网页访问是一种非常耗时的操作,所以,我们在这里新建一个class继承Thread父类,在线程里面重写run方法。
@Override
//run方法是一种在线程中处理网络耗时的方法,这里会抛出一个异常,这个异常是用来解析这个URL是否能够被正常读取的。
public void run() {
try {
URL httpUrl = new URL(url);
try {//针对返回的协议的不同,如果Http协议就用HttpURLConnection,如果是https协议的话,我们就用HttpsURLConnection
HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
//设置请求超时等待的时间,毫秒级别的。
conn.setReadTimeout(5000);
//设置访问方式,我们一般用GET方式去访问一个网页,请求网络数据。
conn.setRequestMethod("GET");
/*从网上下载图片*/
//拿到一个conn的输入流
conn.setDoInput(true);
InputStream in = conn.getInputStream();
FileOutputStream out = null;
File downloadFlie = null;
//由system.currentTimeMillis() 获得当前的时间,再强制转化成String类型,赋给fileName。
String fileName = String.valueOf(System.currentTimeMillis());
//创建图片下载的目录,先判断目录是否存在,
//Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)就是判断SD卡挂在与否的语句,为真则SD卡挂载成功。
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File parent = Environment.getExternalStorageDirectory();//父目录的位置
//新建文件输出目录
downloadFlie = new File(parent, fileName);
out = new FileOutputStream(downloadFlie);
}
//新建文件输出目录,新建文件输出目录之后,我们要使用这个InputStream类的流来读取网上的图片
//创建一个2k长度的缓冲区
byte[] b = new byte[2*1024];
int len;
if(out!=null){
while((len=in.read(b))!=-1){//len!=-1的话。我们认为它一直有数据
out.write(b, 0, len);//往这个缓冲区里面写东西,有多长写多长。从0开始到len
}
}
//通过BitmapFactory的decodeFile方法来传入一个文件的名字,Bitmap是Android系统中的图像处理的最重要类之一。称之为位图。
//用它可以获取图像文件信息,进行图像剪切、旋转、缩放等操作,并可以指定格式保存图像文件。
//getAbsolutePath方法是用来获取文件的绝对路径的。将下载了的文件(downloadFlie)在本地进行解析,转化成bitmap。这里使用的是decodeFile方法。
final Bitmap bitmap = BitmapFactory.decodeFile(downloadFlie.getAbsolutePath());
//由handler来更新UI,利用post方法向主线程发送消息,使用ImageView的setImageBitmap方法设置ImageView显示出下载下来的图片。
handler.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
imageview.setImageBitmap(bitmap);
}
});
/*向webview中传入网站*/
/* //创建一个StringBuffer来缓冲回传的网页数据
final StringBuffer sb = new StringBuffer();
//把网站回传的数据的输入流转换成字节流,InputStreamReader类的传递的是一个InputStream对象。
//通过conn的getInputStream方法可以拿到一个读入流,这个读入流就是网页通过这个网址给我们回传的一个网页内容的信息。
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
//通过每读一行的方法把数据读入到BufferedReader缓冲区里面去。
String str;
while((str = reader.readLine())!=null){
//往StringBuffer中填充数据
sb.append(str);
}
//在handler这个线程下调用handler的post方法,将BufferedReader缓冲区里的数据传给主线程控制webview展示
handler.post(new Runnable() {
//显示网页和子显示图片是不同的,所以run方法不一样。
@Override
public void run() {
// TODO Auto-generated method stub
//调用webview的loadData方法来下载我们提前缓存在BufferedReader里的网页数据并转化成toString(),再展示出来。
//mimeType就是网页源码中的content的内容,这里我们用百度的网页。mimeType=text/html;charset=utf-8
webview.loadData(sb.toString(),"text/html;charset=utf-8", null);
}
});*/
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
注意事项
1)、在AndroidManifest.xml中添加网络访问的权限和设置一个将信息保存在外置SD卡上的权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
2)、实际上文件是展示在客户端得,并没有存储在客户端。
3)、Handler的具体意义。相关文章
4)Bitmap的具体意思Bitmap百度百科