网络编程之URL与Http

转发请注明出处:http://blog.csdn.net/qq_28055429/article/details/52047347

ONE  ------       URL:

一,基本知识:

(1)全称:Uniform Resource Locator  

(2)中文名: 统一资源定位器

3)组成:协议名,主机,端口和资源(protocol://host:port/resourceName

如:http://www.crazyit.org/index.php

二,基本方法:

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

三,使用openStream(): 例子:读取图片:
(1) 创建URL对象

URL   url  =  new URL(Str);//Str为你要图片的网络地址
(2)用openStream()方法打开输入流,返回一个InputStream对象
InputStream  is  =  url.openStream();
(3)去执行你想要的结果的相关操作,如读取图片:
Bitmap  bitmap  =  BitmapFactory.decodeStream(is);
Msg.obj  =  bitmap ;//这里把图片作为参数,传给handler,然后去显示,
 			//发送完后记得关闭流,is.close();

如,将图片下载到本地:
//创建输出流,参数:名字,参数2:模式
	OutputStream  os = openFileOutput(“crazyit.pne” , MODE_WORLD_READABLE);
	Byte[]  buff  =  new byte[1024];		//一个字节的度
	Int  hasRead  = 0 ;
	While( ( hasRead  = is.read(buff) )  > 0)	
	{
		Os.write(buff , 0 , hasRead);		//写入
	}
	Is.close();		//关闭输入输出流
	os.close();

四 ,使用URL的openConnection方法来提交请求

步骤一:通过使用URL对象的openConnection()方法来创建URLConnection对象

步骤二:设置URLConnection的参数和普通请求属性
步骤三:
GET请求 :使用connect方法来建立和远程资源之间的实际连接
POST请求:需要获取URLConnection实例对应的输出流来发送请求参数
步骤四:
  远程资源变为可用,程序可访问远程资源的头字段,或通过输入流读取远程资源的数据
 在建立和远程资源的实际连接之前,可设置请求头字段:

setAllowUserInteraction :设置该URLConnection的allowUserInteraction请求头字段的值
  setDoInput  :…….doInput请求头字段的值
  setDoOutput :…….doOutput请求头字段的值
  setIfModifiedSince  :  ……..ifModifiedSince请求头字段的值
  setUseCaches : …..useCaches请求头字段的值
另外方法: 
 setRequestProperty(String key , String value):设置该URLConnection的key请求头字段的值为value(此方法经常用):如,conn.setRequestProperty(“accept” , “*/*”);
  addRequestProperty(String key , String value):为该URLConnection的key请求头字段增加value值,该方法不会覆盖原请求头字段的值,而是将新增的值追加到原请求头字段中
当程序资源可用后,出现可用下面方法访问头字段和内容:
<pre name="code" class="java">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响应头字段的值

<span style="color:#cc0000;">(1)	GET请求</span>
创建URL对象:
		URL  readUrl  = new URL(url);
使用URLConnection打开链接
		URLConnection conn  =  readUrl.openConnection();
建立前设置相关属性,然后用connect()建立实际连接
Conn.setRequestProperty(“accept” , “*/*’);
…..
conn.connect();
实际建立后,可获取相关响应头字段值:最后记得关闭流

…….
<span style="color:#cc0000;">(2)	POST请求</span>
创建URL对象:
		URL  readUrl  = new URL(url);
使用URLConnection打开链接
		URLConnection conn  =  readUrl.openConnection();
建立前设置相关属性,获取输出流来发送请求参数 
Conn.setRequestProperty(“accept” , “*/*’);
……
conn.setDoOutput(true);
conn.setDoInput(true);   //这两行是必须的
out  = new PrintWriter(conn.getOutputStream());	//也可通过别的方法来获取,
out.print(params)
out.flush():
然后,记得关闭两个流
因为与下面的HTTP中的HttpURLConnection有密切关系,例子就在HttpURLConnection里面了(详见例子2)

TWO   ----   HTTP:

一,基本知识:

(1)全称:Hypertext transfer protocol

(2)中文意思:超文本传送协议

(3)解释:面向应用层的可靠传输协议

二,常用有两种:HttpURLConnection和HttpClient

<1>HttpURLConnection的使用:

基本方法:

int  getResponseCode() :获取服务器的响应代码

String getResponseMessage() :获取服务器的响应消息

String  getRequestMethod():获取发送请求的方法

void setRequestMethod(String  method) :设置发送请求的方法

具体使用如下:

GET访问:

一,HttpURLConnection链接网络:

假如得到某个网址:String path = " http:XXXX";

假如是一张图片网址:String path = "http://p4.so.qhimg.com/t01b4d668163834560e.jpg";

那么开始链接:

(1)用URL把网址封装

URL   url = new    URL(path) ;

(2)用URL.openConnection()方法打开连接,返回一个URLConnection对象

HttpURLConnection    conn    =  (HttpURLConnection) url.openConnection();

(3)设置请求方法,可以查看ie浏览器等,请求为--GET

<pre name="code" class="java">conn.setRequestMethod("GET");    //设置方法GET


(4)设置时间:

conn.setConnectTimeout(5000);    //客户端连接服务端的时间
          // conn.setReadTimeout(5000); 设置从服务端下载来本地显示的时间,
           //如显示时突然断网了,图片刚好显示一半,那么这个时候要怎么处理呢?就是这个时间

(5)设置哪个浏览器范围:

 // conn.setRequestProperty(参数1,参数2);设置连接的浏览器,可以通过ie等查看

(6)获取返回码:200代表正常, 400----错误请求 , 404----找不到

int result =  conn.getResponseCode();     //得到返回码,200正常,

(7)然后开始处理

if(result    ==  200){
               //获取输入流对象
               InputStream is =  conn.getInputStream();
               //利用BitmapFactory.decodeStream()方法得到Bitmap对象,该方法接受一个InputStream对象
               Bitmap   bitmap  =   BitmapFactory.decodeStream(is);
               imageView.setImageBitmap(bitmap);
           }
           else {
               Toast.makeText(this , "显示图片失败" , Toast.LENGTH_SHORT).show();
           }

这段代码是有问题的,因为在android4.0之后就不允许在主线程访问网络,,

具体例子:访问图片

布局文件activity_layout:

<?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">
    <ImageView
        android:id="@+id/ig_view"
        android:layout_weight="1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <EditText
        android:text=""
        android:singleLine="true"
        android:hint="请输入网址"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/et_view"/>
    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="浏览"
        android:id="@+id/button"
        android:onClick="find_photo"/>
</LinearLayout>


主类:MainActivity

public class MainActivity extends AppCompatActivity {
    private EditText editText ;
    private ImageView imageView ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        

        editText    =   (EditText)findViewById(R.id.et_view);
        imageView   =   (ImageView)findViewById(R.id.ig_view);

    }
   public void  find_photo(View view){
        String str_txt  =   editText.getText().toString().trim() ;
       try {
           //包装成URL对象
           URL url = new URL(str_txt);
           //用url.openConnection()打开连接,返回一个URLConnection对象,
           //因为前面用URL包装,故而用HttpURL,还有别的种类,如https等
           HttpURLConnection    conn    =  (HttpURLConnection) url.openConnection();
           conn.setRequestMethod("GET");    //设置方法GET
           conn.setConnectTimeout(5000);    //客户端连接服务端的时间
          // conn.setReadTimeout(5000); 设置从服务端下载来本地显示的时间,
           //如显示时突然断网了,图片刚好显示一半,那么这个时候要怎么处理呢?就是这个时间
          // conn.setRequestProperty(参数1,参数2);设置连接的浏览器,可以通过ie等查看
          int result =  conn.getResponseCode();     //得到返回码,200正常,
           if(result    ==  200){
               //获取输入流对象
               InputStream is =  conn.getInputStream();
               //利用BitmapFactory.decodeStream()方法得到Bitmap对象,该方法接受一个InputStream对象
               Bitmap   bitmap  =   BitmapFactory.decodeStream(is);
               imageView.setImageBitmap(bitmap);
           }
           else {
               Toast.makeText(this , "显示图片失败" , Toast.LENGTH_SHORT).show();
           }
       }catch (Exception e){
           e.printStackTrace();
           Toast.makeText(this , "获取图片失败" , Toast.LENGTH_SHORT).show();
       }
    }
}


记得添加网络权限:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

结果:如果你是在android4.0之后的,会出现,访问失败

如果不是则没问题:

这个时候,你可能说,那就在子线程访问网络啊,new一个线程

代码:

public void  find_photo(View view){
        final  String str_txt  =   editText.getText().toString().trim() ;
        new   Thread(){
            @Override
            public void run() {
                try {
                    //包装成URL对象
                    URL url = new URL(str_txt);
                    //用url.openConnection()打开连接,返回一个URLConnection对象,
                    //因为前面用URL包装,故而用HttpURL,还有别的种类,如https等
                    HttpURLConnection    conn    =  (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");    //设置方法GET
                    conn.setConnectTimeout(5000);    //客户端连接服务端的时间
                    // conn.setReadTimeout(5000); 设置从服务端下载来本地显示的时间,
                    //如显示时突然断网了,图片刚好显示一半,那么这个时候要怎么处理呢?就是这个时间
                    // conn.setRequestProperty(参数1,参数2);设置连接的浏览器,可以通过ie等查看
                    int result =  conn.getResponseCode();     //得到返回码,200正常,
                    if(result    ==  200){
                        //获取输入流对象
                        InputStream is =  conn.getInputStream();
                        //利用BitmapFactory.decodeStream()方法得到Bitmap对象,该方法接受一个InputStream对象
                        Bitmap   bitmap  =   BitmapFactory.decodeStream(is);
                        imageView.setImageBitmap(bitmap);
                    }
                    else {
                        Toast.makeText(MainActivity.this , "显示图片失败" , Toast.LENGTH_SHORT).show();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    Toast.makeText(MainActivity.this , "获取图片失败" , Toast.LENGTH_SHORT).show();
                }
            }
        }.start();

    }
结果:没反应,过一会儿,提示:XX应用已经停止应用
因为,安卓4.0后不允许在子线程中更新UI,只能在主线程更新UI)

那么怎么办呢,请看下面:

二,解决主线程不能范围网络的方法:两种
第一种:(不推荐)  

 //注意在Android 4.0之后系统强制性的不允许在主线程访问网络,否则会出现android.os.NetworkOnMainThreadException异常,
        //常用解决办法是:在onCreat()方法的setContentView()语句之后添加以下句子,此处就加在这里吧
        if(android.os.Build.VERSION.SDK_INT > 9){
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
       }

第二种:利用Handler机制:(子线程访问网络,主线程更新UI)

1,基本知识:理解Handler的机制,如图



理解:

(1)先在主线程中创建一个Handler对象,如下:

private Handler handler =  new Handler(){ };

(2)在子线程中处理数据,并利用handler.sendMessage(message);发送消息,如下:

if(result    ==  200){
                        //获取输入流对象
                        InputStream is    =  conn.getInputStream();
                        //利用BitmapFactory.decodeStream()方法得到Bitmap对象,该方法接受一个InputStream对象
                        Bitmap   bitmap   =   BitmapFactory.decodeStream(is);
                        Message  message  =   new Message();
                        message.what      =     CHANGE_UI ;     //设置访问类型,int类型值,自定义CHANGE_UI = 1;
                        message.obj       =     bitmap ;     //设置message的数据
                        handler.sendMessage(message);
                    }

(3)主线程中的Handler会把消息放入message queue,一旦message queue有消息,looper便会循环取出消息,调用

handleMessage()方法来处理消息:代码如下:

private Handler handler =  new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1){ //判断消息的类型
                Bitmap  bt  =  (Bitmap) msg.obj; //取出数据
                imageView.setImageBitmap(bt);
            }
        }
    };

完整代码:

package phototest.maiyu.cai;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
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.Toast;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

public class MainActivity extends AppCompatActivity {
    private EditText editText ;
    private ImageView imageView ;
    private static int CHANGE_UI = 1;
    private static int ERROR_UI  = 2;
    private Handler handler =  new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1){ //判断消息的类型
                Bitmap  bt  =  (Bitmap) msg.obj; //取出数据
                imageView.setImageBitmap(bt);
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText    =   (EditText)findViewById(R.id.et_view);
        imageView   =   (ImageView)findViewById(R.id.ig_view);

    }
   public void  find_photo(View view){
        final  String str_txt  =   editText.getText().toString().trim() ;
        new   Thread(){
            @Override
            public void run() {
                try {
                    //包装成URL对象
                    URL url = new URL(str_txt);
                    //用url.openConnection()打开连接,返回一个URLConnection对象,
                    //因为前面用URL包装,故而用HttpURL,还有别的种类,如https等
                    HttpURLConnection    conn    =  (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");    //设置方法GET
                    conn.setConnectTimeout(5000);    //客户端连接服务端的时间
                    // conn.setReadTimeout(5000); 设置从服务端下载来本地显示的时间,
                    //如显示时突然断网了,图片刚好显示一半,那么这个时候要怎么处理呢?就是这个时间
                    // conn.setRequestProperty(参数1,参数2);设置连接的浏览器,可以通过ie等查看
                    int result =  conn.getResponseCode();     //得到返回码,200正常,
                    if(result    ==  200){
                        //获取输入流对象
                        InputStream is    =  conn.getInputStream();
                        //利用BitmapFactory.decodeStream()方法得到Bitmap对象,该方法接受一个InputStream对象
                        Bitmap   bitmap   =   BitmapFactory.decodeStream(is);
                        Message  message  =   new Message();
                        message.what      =     CHANGE_UI ;     //设置访问类型,int类型值,自定义CHANGE_UI = 1;
                        message.obj       =     bitmap ;     //设置message的数据
                        handler.sendMessage(message);
                    }
                    else {
                        Toast.makeText(MainActivity.this , "显示图片失败" , Toast.LENGTH_SHORT).show();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    Toast.makeText(MainActivity.this , "获取图片失败" , Toast.LENGTH_SHORT).show();
                }
            }
        }.start();

    }
}
输入正确图片地址:就会出现一张图片了

但是如果地址错误,又会出现:该应用已经停止运行,,,

原因:还是在子线程处理了UI

else {
                        Toast.makeText(MainActivity.this , "显示图片失败" , Toast.LENGTH_SHORT).show();
                    }

更改如下:

 else {
                        Message  message  =   new Message();
                        message.what      =     ERROR_UI ;     //设置访问类型,int类型值,自定义ERROR_UI=2;
                        handler.sendMessage(message);
                    }
在Handler的handleMessage()方法中添加:

else if(msg.what    ==  ERROR_UI){
                Toast.makeText(MainActivity.this , "显示图片失败" ,Toast.LENGTH_SHORT).show();
            }
完整代码:

<pre name="code" class="java">package phototest.maiyu.cai;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

public class MainActivity extends AppCompatActivity {
    private EditText editText ;
    private ImageView imageView ;
    private static int CHANGE_UI = 1;
    private static int ERROR_UI  = 2;
    private Handler handler =  new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == CHANGE_UI){ //判断消息的类型
                Bitmap  bt  =  (Bitmap) msg.obj; //取出数据
                imageView.setImageBitmap(bt);
            }
            else if(msg.what    ==  ERROR_UI){
                Toast.makeText(MainActivity.this , "显示图片失败" ,Toast.LENGTH_SHORT).show();
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText    =   (EditText)findViewById(R.id.et_view);
        imageView   =   (ImageView)findViewById(R.id.ig_view);

    }
   public void  find_photo(View view) {
       final String str_txt = editText.getText().toString().trim();
       if (!TextUtils.isEmpty(str_txt)) {
           new Thread() {
               @Override
               public void run() {
                   try {
                       //包装成URL对象
                       URL url = new URL(str_txt);
                       //用url.openConnection()打开连接,返回一个URLConnection对象,
                       //因为前面用URL包装,故而用HttpURL,还有别的种类,如https等
                       HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                       conn.setRequestMethod("GET");    //设置方法GET
                       conn.setConnectTimeout(5000);    //客户端连接服务端的时间
                       // conn.setReadTimeout(5000); 设置从服务端下载来本地显示的时间,
                       //如显示时突然断网了,图片刚好显示一半,那么这个时候要怎么处理呢?就是这个时间
                       // conn.setRequestProperty(参数1,参数2);设置连接的浏览器,可以通过ie等查看
                       int result = conn.getResponseCode();     //得到返回码,200正常,
                       if (result == 200) {
                           //获取输入流对象
                           InputStream is = conn.getInputStream();
                           //利用BitmapFactory.decodeStream()方法得到Bitmap对象,该方法接受一个InputStream对象
                           Bitmap bitmap = BitmapFactory.decodeStream(is);
                           Message message = new Message();
                           message.what = CHANGE_UI;     //设置访问类型,int类型值,自定义CHANGE_UI = 1;
                           message.obj = bitmap;     //设置message的数据
                           handler.sendMessage(message);
                       } else {
                           Message message = new Message();
                           message.what = ERROR_UI;     //设置访问类型,int类型值,自定义ERROR_UI=2;
                           handler.sendMessage(message);
                       }
                   } catch (Exception e) {
                       e.printStackTrace();
                       Toast.makeText(MainActivity.this, "获取图片失败", Toast.LENGTH_SHORT).show();
                   }
               }
           }.start();
       }
       else{
           Toast.makeText(MainActivity.this, "路径不能为空" , Toast.LENGTH_SHORT).show();
       }
   }
}


结果:

当地址不正确时,Toast提示,

当正确时,出现图片

附加一张效果图:

如果要访问显示网址源代码,可以这样解析:

public class StreamTools {
    public static String readInputStream(InputStream is){
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int len = 0;
            byte[] buffer = new byte[1024] ;
            while((len = is.read(buffer)) != -1){
                baos.write(buffer , 0 , len);

            }
            is.close();
            baos.close();
            byte[] result = baos.toByteArray();
            return new String(result);

        }catch (Exception e){
            e.printStackTrace();
            return "错误";
        }
    }
}

POST访问:见例子代码:

例子2:

布局:activity_httpurlconn:采用线性布局,放置一个TextView用于提示,两个按钮(get和post),

一个ScrollView(里面放置一个TextView)用于显示内容

代码如下:

<?xml version="1.0" encoding="utf-8"?>
<!-- 定义基本布局:LinearLayout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <!-- 提示的TextView -->
    <TextView
        android:id="@+id/TextView01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/tv_httpurlconn" >
    </TextView>

    <!-- get请求 -->
    <Button
        android:id="@+id/Button01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btn01_httpurlconn" >
    </Button>

    <!-- post请求 -->
    <Button
        android:id="@+id/Button02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btn02_httpurlconn" >
    </Button>
    <!-- ScrollView:里面放置一个TextView用于显示响应的结果 -->
    <ScrollView
        android:id="@+id/ScrollView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >
        <TextView
            android:id="@+id/TextView02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
        </TextView>
    </ScrollView>

</LinearLayout>
字符串资源:

    <string name="tv_httpurlconn">HttpURLConnection网络测速</string>
    <string name="btn01_httpurlconn">get请求手机网站</string>
    <string name="btn02_httpurlconn">post请求CSDN博客</string>
主类:代码如下:

package com.example.s08_01.activity;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.s08_01.R;

public class HttpURLConnectionActivity extends Activity {

	private TextView tv = null; // 定义TextView
	private Button httpget, httppost;// 定义get按钮和post按钮
	private String googleWeatherUrl =  "http://3g.renren.com/login.do";
	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (msg.what == 1) {
				Toast.makeText(getApplicationContext(), "连接手机网站成功!",
						Toast.LENGTH_SHORT).show();
				String str = (String) msg.obj;
				tv.setText(str);
			} else if (msg.what == 2) {
				Toast.makeText(getApplicationContext(), "连接手机网站失败",
						Toast.LENGTH_SHORT).show();
			} else if (msg.what == 3) {
				Toast.makeText(getApplicationContext(), "连接CSDN博客成功!",
						Toast.LENGTH_SHORT).show();
				String str = (String) msg.obj;
				tv.setText(str);
			} else if (msg.what == 4) {
				Toast.makeText(getApplicationContext(), "连接CSDN博客失败",
						Toast.LENGTH_SHORT).show();
			}
		};
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_httpurlconn);
		findView(); // 为控件绑定ID
		setListener(); // 为控件设置监听
	}

	// 为控件设置监听
	private void setListener() {
		// get请求
		httpget.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new Thread() {
					public void run() {
						urlGetConn(); // 新开线程去请求
					};
				}.start();
			}
		});

		// post请求
		httppost.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new Thread() {
					public void run() {
						urlPostConn(); // 主线程请求
					};
				}.start();
			}
		});

	}

	// 为控件绑定ID
	private void findView() {
		tv = (TextView) findViewById(R.id.TextView02);
		httpget = (Button) findViewById(R.id.Button01);
		httppost = (Button) findViewById(R.id.Button02);
	}

	// 使用URLConnection get连接GoogleWeatherAPI
	protected void urlGetConn() {
		Message msg = new Message(); // 创建Message对象
		try {
			// 创建URL对象,并传入地址
			URL url = new URL(googleWeatherUrl);
			// 用URL的openConnection()方法打开连接,并获取HttpURLConnection
			HttpURLConnection httpconn = (HttpURLConnection) url
					.openConnection();
			// 若请求结果成功
			if (httpconn.getResponseCode() == HttpURLConnection.HTTP_OK) {

				// InputStreamReader
				InputStreamReader isr = new InputStreamReader(
						httpconn.getInputStream(), "utf-8");
				int i;
				String content = "";
				// read
				while ((i = isr.read()) != -1) {
					content = content + (char) i;
				}
				msg.obj = content;
				msg.what = 1;
				handler.sendMessage(msg);
				isr.close();
				// 设置TextView
			}
			// disconnect
			httpconn.disconnect();
		} catch (Exception e) {
			msg.what = 2;
			handler.sendMessage(msg);
		}
	}

	public void urlPostConn() {
		String httpUrl = "http://www.csdn.net/";
		String resultData = "";
		URL url = null;
		Message msg = new Message();
		try {
			// 创建URL对象
			url = new URL(httpUrl);
		} catch (MalformedURLException e) {
			msg.what = 2;
			handler.sendMessage(msg);
		}
		if (url != null) {
			try {
				// 使用HttpURLConnection打开连接
				HttpURLConnection urlConn = (HttpURLConnection) url
						.openConnection();
				
				// 因为要求使用Post方式提交数据,需要设置为true
				urlConn.setDoOutput(true);
				urlConn.setDoInput(true);
				
				// 设置以Post方式,注意此处的“POST”必须大写
				urlConn.setRequestMethod("POST");
				
				// Post 请求不能使用缓存
				urlConn.setUseCaches(false);
				urlConn.setInstanceFollowRedirects(true);
				
				// 配置本次连接的Content-Type,配置为application/x-www-form-urlencoded
				urlConn.setRequestProperty("Content-Type",
						"application/x-www-form-urlencoded");
				// 连接,从postUrl.openConnection()至此的配置必须在connect之前完成
				// 要注意的事connection.getOutputStream会隐含地进行connect。
				urlConn.connect();

				// DataOutputStream流上传数据
				DataOutputStream out = new DataOutputStream(
						urlConn.getOutputStream());
				// 要上传的参数
				String content = "par="
						+ URLEncoder.encode("POSTTransferData", "gb2312");
				// 将要上传的内容写入流中
				out.writeBytes(content);
				// 刷新,关闭
				out.flush();
				out.close();
				// 得到读取的数据
				InputStreamReader in = new InputStreamReader(
						urlConn.getInputStream());
				BufferedReader buffer = new BufferedReader(in);
				String str = null;
				while ((str = buffer.readLine()) != null) {
					resultData += str + "\n";
				}
				in.close();
				urlConn.disconnect();

				msg.obj = resultData;
				msg.what = 3;
				handler.sendMessage(msg);

			} catch (IOException e) {
				msg.what = 4;
				handler.sendMessage(msg);
			}
		}// if(url!=null)
		else {
			msg.what = 4;
			handler.sendMessage(msg);
		}
	}

}
记得添加网络权限:

 <uses-permission android:name="android.permission.INTERNET" />
结果:略,,,

增强版的HttpURLConnection      --------- >>     HttpClient的使用:

(1)创建HttpClient对象

(2)设置GET请求(创建HttpGet对象)或者设置POST请求(创建HttpPost对象)

(3)设置请求参数:

GET  ---  setParams(HttpParams  params)

POST ----setParams(HttpParams params)或者setEntity(HttpEntity  entity)方法

(4)调用HttpClient对象的execute(HttpUriRequest  request)发送请求,返回一个HttpResponse对象

(5)调用HttpResponse的

                      ------getAllHeaders(),getHeaders(String name)获取服务器的请求头

   -----getEntity()获取HttpEntity对象(里面包含了服务器的响应内容),可通过该对象获取服务器的响应内容,如:String result = EntityUtils.toString(httpResponse.getEntity())

可以得到结果,


下面例子用get和post方法来访问百度首页:

布局文件:activity_httpclient:常用LinearLayout,里面放置一个TextView用于提示,两个按钮(get请求和post请求),

和一个ScrollView(里面放置一个TextView)用于显示响应的内容:

<?xml version="1.0" encoding="utf-8"?>
<!-- 定义基本布局:LinearLayout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
	<!-- 文本提示 -->
    <TextView
        android:id="@+id/TextView01"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/httpclient_tv01" >
    </TextView>

    <!-- GET访问按钮 -->
    <Button
        android:id="@+id/Button01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/httpclient_btn01" >
    </Button>
   <!-- POST访问按钮 -->
    <Button
        android:id="@+id/Button02"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/httpclient_btn02" >     
    </Button>
   <!-- 定义ScrollView(里面放置TextView)用来显示结果 -->
    <ScrollView
        android:id="@+id/ScrollView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/TextView02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
        </TextView>
    </ScrollView>

</LinearLayout>

字符串资源:

    <string name="httpclient_tv01">HttpClient网络测速</string>
    <string name="httpclient_btn01">Get访问百度</string>
    <string name="httpclient_btn02">POST访问百度</string>

主类:采用handler+message去处理访问网络,具体代码如下:

package com.example.s08_01.activity;

import org.apache.http.HttpResponse;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.s08_01.R;

public class HttpClientActivity extends Activity {
	private TextView tv = null; // 定义文本显示内容
	private String testUrl = "http://www.baidu.com"; // 定义百度地址
	private Button httpget, httppost; // 定义按钮

	// 创建线程,重写handleMessage方法
	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (msg.what == 1) { // msg.what为1时,表示请求成功
				Toast.makeText(getApplicationContext(), "连接成功!",
						Toast.LENGTH_SHORT).show(); // Toast提示
				// 设置TextView
				String str = (String) msg.obj; // 把传回来的参数转化为字符串类型,然后显示出来
				tv.setText(str);
			} else if (msg.what == 2) { // 连接失败
				Toast.makeText(getApplicationContext(), "连接失败",
						Toast.LENGTH_SHORT).show();
				tv.setText("链接失败 ");
			}
		};
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_httpclient);
		findView(); // 为控件绑定ID
		setListener(); // 为控件设置监听
	}

	//为控件设置监听
	private void setListener() {
		//get请求监听
		httpget.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new Thread() {			//创建子线程,
					public void run() {
						httpClientGet();	//get请求
					};
				}.start();

			}
		});

		//post请求监听
		httppost.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new Thread() {		//创建子线程
					public void run() {
						httpClientPost();	//post请求
					};
				}.start();

			}
		});

	}

	//为控件绑定id
	private void findView() {
		tv = (TextView) findViewById(R.id.TextView02);
		httpget = (Button) findViewById(R.id.Button01);
		httppost = (Button) findViewById(R.id.Button02);
	}

	//get请求
	protected void httpClientGet() {
		// 创建DefaultHttpClient对象
		DefaultHttpClient httpclient = new DefaultHttpClient();
		// 设置为GET请求:即创建HttpGet对象
		HttpGet httpget = new HttpGet(testUrl);
		// 创建ResponseHandler
		//ResponseHandler<String> responseHandler = new BasicResponseHandler();
		Message message = new Message();	//创建Message对象

		try {
			
			//调用HttpClient的execute方法发送请求,返回一个HttpResponse对象		
			HttpResponse httpResponse = httpclient.execute(httpget);	
			// 发送请求并获取反馈
			// 解析返回的内容
			//调用HttpResponse的getEntity()方法获取HttpEntity对象(里面包装了服务内容)
			String content = EntityUtils.toString(httpResponse.getEntity());  
			//获取内容
			//String content = httpclient.execute(httpget, responseHandler);
			message.obj = content;	//设置参数obj,what,
			message.what = 1;
			handler.sendMessage(message);	//发送给主线程

		} catch (Exception e) {
			//错误
			message.what = 2;
			handler.sendMessage(message);

		}
		httpclient.getConnectionManager().shutdown();
	}

	//post请求
	protected void httpClientPost() {
		Message message = new Message();
		try {
			DefaultHttpClient httpclient = new DefaultHttpClient();  //创建DefaultHttpClient对象
			HttpPost httppost = new HttpPost(testUrl);				//设置为POST请求:即创建HttpPost对象
			HttpResponse httpResponse = httpclient.execute(httppost);	//调用HttpClient的execute方法发送请求,返回一个HttpResponse对象		
			// 发送请求并获取反馈
			// 解析返回的内容
			String result = EntityUtils.toString(httpResponse.getEntity());  //调用HttpResponse的getEntity()方法获取HttpEntity对象(里面包装了服务内容)
			message.what = 1;
			message.obj = result;
			handler.sendMessage(message);

		} catch (Exception e) {
			message.what = 2;
			handler.sendMessage(message);
		}
	}
}

记得添加网络权限:

       <!-- 授予访问互联网权限 -->
    <uses-permission android:name="android.permission.INTERNET" />

然后,结果就出来了...略






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章