URL(Uniform Resource Locator)
**对象代表**统一资源定位器
**,**
是**指向互联网“资源”
**的**指针
**。
这里的资源可以是**简单的文件或目录
**,
也可以是**对更为复杂的对象引用
**,
例如对**数据库
**或**搜索引擎
**的**查询
**。协议名、主机、端口和资源
**组成,
满足如下的格式
protocol://host:port/resourceName
http://www.oneedu.cn/Index.htm
URL
**获取网络资源,
其中的**URLConnection
**和**HTTPURLConnection
**
是最为常用的两种方式。URI(Uniform Resource Identifiers)
**类,
其实例代表一个**统一资源标识符
**,
Java的URI**不能用于定位任何资源
**,
它的**唯一作用
**就是**解析
**。URL
**则**包含
**一个**可打开到达该资源
**的**输入流
**,**
因此我们可以将**URL
**理解成**URI的特例
**。类URL
**中,
提供了**多个
**可以创建URL对象的**构造器
**,
一旦获得了**URL对象
**之后,
可以调用下面的方法来访问**该URL对应的资源
**。String getFile()
:获取此URL的资源名
。String getHost()
:获取此URL的主机名
。String getPath()
:获取此URL的路径部分
。int getPort()
:获取此URL的端口号
。String getProtocol()
:获取此URL的协议名称
。String getQuery()
:获取此URL的查询字符串部分
。URLConnection openConnection()
:
返回一个URLConnection对象
,
它表示到URL所引用的远程对象的连接
。InputStream openStream()
:
打开与此 URL 的连接
,
并返回一个用于读取该 URL 资源
的InputStream
。URL
**中,
可以使用方法**openConnection()
**返回一个**URLConnection
**对象,
该对象表示**应用程序
**和**URL
**之间的**通信链接
**。应用程序
**可以通过**URLConnection实例
向此**URL
**发送**请求
**,
并读取URL**引用的资源
**。
创建
**一个**和URL连接
**,**
并发送**请求
**;openConnection()
方法来创建URLConnection
对象。URLConnection
的参数
和普通请求属性
。Get 方式
请求,使用方法 connect
建立和远程资源
之间的实际连接
即可;
如果需要发送Post
方式请求,
需要获取URLConnection实例
对应的输出流
来发送请求参数
。远程资源
变为可用
,
程序可以访问远程资源的头字段
或通过输入流
读取
远程资源的数据
。建立
和远程资源的实际连接之前
,
可以通过如下方法来设置请求头字段
。 setAllowUserInteraction
:设置该URLConnection的allowUserInteraction请求头字段的值。setDoInput
:设置该URLConnection的doInput请求头字段的值。setDoOutput
:设置该URLConnection的doOutput请求头字段的值。setIfModifiedSince
:设置该URLConnection的ifModifiedSince请求头字段的值。setUseCaches
:设置该URLConnection的useCaches请求头字段的值。
除此之外,还可以使用如下方法来设置或增加通用头字段。setRequestProperty(String key, String value)
:设置该URLConnection的key请求头字段的值为value。addRequestProperty(String key, String value)
:为该URLConnection的key请求头字段的增加value值,该方法并不会覆盖原请求头字段的值,而是将新值追加到原请求头字段中。远程资源
可以使用
后,
使用如下方法访问头字段和内容
。 Object getContent()
:获取该URLConnection的内容。String getHeaderField(String name)
:获取指定响应头字段的值。getInputStream()
:返回该URLConnection对应的输入流,用于获取URLConnection响应的内容。getOutputStream()
:返回该URLConnection对应的输出流,用于向URLConnection发送请求参数。getHeaderField
:根据响应头字段来返回对应的值。
因为在程序中需要经常访问某些头字段,所以Java为我们提供了如下方法来访问特定响应头字段的值。getContentEncoding
:获取content-encoding响应头字段的值。getContentLength
:获取content-length响应头字段的值。getContentType
:获取content-type响应头字段的值。getDate()
:获取date响应头字段的值。getExpiration()
:获取expires响应头字段的值。getLastModified()
:获取last-modified响应头字段的值。public class UseInetAddress {
public UseInetAddress() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args)
throws Exception
{
//根据主机名来获取对应的InetAddress实例
InetAddress ip = InetAddress.getByName("www.sohu.com");
//判断是否可达
System.out.println("sohu是否可达:" + ip.isReachable(2000));
//获取该InetAddress实例的IP字符串
System.out.println(ip.getHostAddress());
//根据原始IP地址来获取对应的InetAddress实例
InetAddress local = InetAddress.getByAddress(new byte[]{127,0,0,1});
System.out.println("本机是否可达:" + local.isReachable(5000));
//获取该InetAddress实例对应的全限定域名
System.out.println(local.getCanonicalHostName());
}
}
运行效果:
sohu是否可达:true
14.18.240.22
本机是否可达:true
127.0.0.1
凌川江雪阁是否可达:true
47.100.78.251
注意:
public class URLDecodery {
public static void main(String[] args)
throws Exception
{
//将application/x-www-form-urlencoded MIME字符串
//转换成普通字符串
String keyWord = URLDecoder.decode(
"%CE%CA%CA%C0%BC%E4%C7%E9%CE%AA%BA%CE%CE%EF", "GBK");
System.out.println(keyWord);
//将普通字符串转换成
//application/x-www-form-urlencoded MIME字符串
String urlStr = URLEncoder.encode("直教人生死相许" , "GBK");
System.out.println(urlStr);
keyWord = URLDecoder.decode("%E7%8B%97%E7%8B%97%E6%90%9E%E7%AC%91", "UTF-8");
System.out.println(keyWord);
}
}
运行结果:
问世间情为何物
%D6%B1%BD%CC%C8%CB%C9%FA%CB%C0%CF%E0%D0%ED
狗狗搞笑
主要分四个功能实现:
(1)创建一个URL对象:
URL url = new URL("http://www.sohu.com");
(2)利用HttpURLConnection对象从网络中获取网页数据:
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
(3)设置连接超时:
conn.setConnectTimeout(6* 1000);
(4)对响应码进行判断:
if (conn.getResponseCode() != 200) throw new RuntimeException("请求url失败");
(5)得到网络返回的输入流:
InputStream is = conn.getInputStream();
接着可以用bufferReader读取数据;
(1)~(5)同上
(6)写出得到的文件流:
outStream.write(buffer, 0, len);
(1)将地址和参数存到byte数组中:
byte[] data = params.toString().getBytes();
(2)创建URL对象:
URL realUrl = new URL(requestUrl);
(3)用HttpURLConnection对象向网络地址发送请求:
HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
(4)设置容许输出:
conn.setDoOutput(true);
(5)设置不使用缓存:
conn.setUseCaches(false);
(6)设置使用Post的方式发送:
conn.setRequestMethod("POST");
(7)设置维持长连接:
conn.setRequestProperty("Connection", "Keep-Alive");
(8)设置文件字符集:
conn.setRequestProperty("Charset", "UTF-8");
(9)设置文件长度:
conn.setRequestProperty("Content-Length", String.valueOf(data.length));
(10)设置文件类型:
conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
(11)最后以流的方式输出。
在实现此功能时, 在发送Post请求时必须设置允许输出。 建议不要使用缓存,避免出现不应该出现的问题。 在开始就用HttpURLConnection对象的setRequestProperty()设置, 即生成HTML文件头。
HttpURLConnection
:
OKHttp
:
注意 使用Android中的HttpUrlConnection时,有个地方需要注意一下, 就是如果程序中有跳转,并且跳转有外部域名的跳转, 那么非常容易超时并抛出域名无法解析的异常(Host Unresolved), 建议做跳转处理的时候不要使用它自带的方法设置成为自动跟随跳转, 最好自己做处理,以防出现异常。 这个问题模拟器上面看不出来,只有真机上面能看出来。
经常不需
**要将**网络中
**的图片 保存到手机中
**,**
而只是**在网络浏览
**一下即可。 这里用 HttpURLConnection
打开连接,
即可**获取连接数据
**了。
在本实例中,
使用**HttpURLConnection
**方法来**连接
**并**获取网络数据
**,
将**获取的数据
**用**InputStream
**的方式**保存
**在**内存
**中。
注意: 这里必须把**
网络请求
**这个**耗时操作
**放在**子线程
**, 否则可能会**阻塞主线程
**,造成报错! (各种乱起八糟的错误, IDE待会儿**什么v4和v7组件库版本
**不匹配的错误都给你搬出来。。。) 主要思路是: 在**子线程
**中进行**网络请求
**, 具体的**网络请求
**操作如上所述 (这里用的是HttpURLConnection
**去连接**远程资源
**,** 实际开发中可以尝试集成第三方库),请求成功
**后** 把得到的资源在子线程编码(**decodeStream()
**)成**bitmap
** 接着把**bitmap
**转交到**主线程
**进行**UI更新
**即可完成!
runOnUiThread()
**把**bitmap
**转交到**主线程
**进行**UI更新
**:public class GetImageActivity extends AppCompatActivity {
private Button mButton1;
private TextView mTextView1;
private ImageView mImageView1;
String uriPic = "http://www.baidu.com/img/baidu_sylogo1.gif";
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_image);
mButton1 = (Button) findViewById(R.id.myButton1);
mTextView1 = (TextView) findViewById(R.id.myTextView1);
mImageView1 = (ImageView) findViewById(R.id.myImageView1);
mButton1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/* 设置Bitmap在ImageView中 */
getURLBitmap();
}
});
}
public void getURLBitmap()
{
new Thread(new Runnable() {
@Override
public void run() {
URL imageUrl = null;
Bitmap bitmap = null;
try {
/* new URL对象将网址传入 */
imageUrl = new URL(uriPic);
} catch (MalformedURLException e)
{
e.printStackTrace();
}
try {
/* 取得连接 */
HttpURLConnection conn = (HttpURLConnection) (imageUrl != null ? imageUrl.openConnection() : null);
if (conn != null) {
conn.connect();
}
/* 取得返回的InputStream */
InputStream is = null;
if (conn != null) {
is = conn.getInputStream();
}
/* !!!!!!!!!!!
将InputStream变成Bitmap
!!!!!!!!!!!!!*/
bitmap = BitmapFactory.decodeStream(is);
showImage(bitmap);
/* 关闭InputStream */
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
private void showImage(final Bitmap bitmap) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mImageView1.setImageBitmap(bitmap);
mTextView1.setText("");
}
});
}
}
对应的xml布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:background="#FFFFFF"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/myTextView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"/>
<Button
android:id="@+id/myButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取网络上的图片" />
<ImageView
android:id="@+id/myImageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
tools:ignore="ContentDescription" />
</LinearLayout>
运行结果:
handle消息机制
**把**bitmap
**转交到**主线程
**进行**UI更新
**:public class GetImageActivityTwo extends AppCompatActivity {
ImageView iv_show;
EditText et_path;
String path;
@SuppressLint("HandlerLeak")
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
Bitmap bitmap = (Bitmap) msg.obj;
iv_show.setImageBitmap(bitmap);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_image_two);
//寻找相应控件
et_path = findViewById(R.id.et_path);
iv_show = findViewById(R.id.iv_show);
}
public void click(View v){
new Thread(){
Message message = Message.obtain();
@Override
public void run() {
File file = new File(getCacheDir(),"test.png");
if(file.exists() && file.length()>=0){
//如果要缓存
// System.out.print("本地缓存");
// Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
// message.obj = bitmap;
// handler.sendMessage(message);
}
else{
path = et_path.getText().toString().trim();
try {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");//设置请求方法
conn.setConnectTimeout(5000);//设置超时时间
InputStream in = conn.getInputStream();//拿到服务器返回的输出流
Bitmap bitmap = BitmapFactory.decodeStream(in);
message.obj = bitmap;
message.what = 2;
handler.sendMessage(message);//发送消息
} catch (Exception e) {
e.printStackTrace();
}
}
}
}.start();
}
}
xml布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".UI.GetImageActivityTwo">
<EditText
android:id="@+id/et_path"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="http://www.baidu.com/img/baidu_sylogo1.gif"
android:hint="请输入图片地址" />
<Button
android:onClick="click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查看" />
<ImageView
android:id="@+id/iv_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
运行结果: