1、httpClient简介
http超文本协议,主要用于在浏览器和服务器间传输html数据。但是在android中也常常被用来交换小数据
httpClient是apache封装的,专门用来处理http请求
2、例子
下面展示的是客户端访问服务器,解析JSON获取一张图片地址,然后根据这个图片地址去下载一张图片并展示
服务器上放的是一个js,里面的内容是一段json数据,如下:
{ "status":"0", "data": { "img_url":"http://xxxx.png", "download_url":"http://xxxx" } }
里面这个img_url就是我们要获取的图片地址
利用http来向服务器请求获取这段json:
import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import org.json.JSONObject; import android.content.Context; import android.graphics.Bitmap; public class ImageUrlGetter {
private static final String LOADING_URL = "http://xxx.js";//访问的就是这个js文件,内容见上 private ImageUrlCallback mCallback; private Context mContext; public interface ImageUrlCallback { public void onGetImgaeDone(Bitmap bm); } public ImageUrlGetter() { } /** * 先拉取imgUrl,然后再根据imgUrl拉取bitmap * * @param callback */ public void getImg(ImageUrlCallback callback) { mCallback = callback; try { HttpEntity entity = getData(LOADING_URL); String entityStr = EntityUtils.toString(entity);//获取json
if (parseJson(new JSONObject(entityStr)) != 0) {//解析json callBack(null); } } catch (Exception e) { callBack(null); } } /** * 请求url,返回httpEntity * * @param url * @return * @throws Exception */ private HttpEntity getData(String url) throws Exception { // HttpClient是个interface HttpClient client = new DefaultHttpClient(); HttpGet get = new HttpGet(new URI(url)); HttpResponse responce = client.execute(get); int status = responce.getStatusLine().getStatusCode(); switch (status) { case HttpStatus.SC_OK://200 case HttpStatus.SC_NOT_MODIFIED://304 return responce.getEntity(); } return null; } /** * 根据远程url去下载图片 * * @param imgUrl * @throws Exception */ private void loadRemoteImage(String imgUrl) throws Exception { if (imgUrl != null) { HttpEntity entity = getData(imgUrl); String sdPath = getSDCardPath(); String imgPath = null; if (sdPath != null) { imgPath = sdPath + "/testImage.png";
//将图片写到本地并回调 FileOutputStream fos = new FileOutputStream(imgPath); fos.write(EntityUtils.toByteArray(entity)); fos.close();
callBack(BitmapFactory.decodeFile(imgPath)); } } } private int parseJson(JSONObject jo) throws Exception { if (jo != null) { int status = jo.getInt("status"); if (status == 0) { JSONObject ja = jo.getJSONObject("data"); String imgUrl = ja.getString("img_url"); loadRemoteImage(imgUrl); return 0; } } return -1; } private void callBack(Bitmap bm) { if (mCallback != null) { if (bm != null) { mCallback.onGetImgaeDone(bm); } else { mCallback.onGetImgaeDone(null); } } } private String getSDCardPath() { return Environment.getExternalStorageDirectory().getAbsolutePath(); } }
这段代码比较简陋,缺乏一些安全性处理。不过android客户端向服务器请求数据,大致就是这样的了,至于请求到的数据是直接处理还是下载到本地再处理,则需要根据实际情况来考虑。
这里只是为了展示http的用法,所以都混在了一起,但在实际运用中,http请求、json的解析、远程图片的拉取等,都建议做封装。在实际操作中,request以及将文件写到本地,都存在超时的可能,所以建议开线程。
在某个activity里面调用
public class TestActivtiy extends Activity implements ImageUrlCallback { private static final int MSG_UPDATE_IMG=1000; private ImageView mImg; @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.test_activity); new ImageUrlGetter(TestActivtiy.this).getImg(this); super.onCreate(savedInstanceState); } private void initUI() { mImg = (ImageView) findViewById(R.id.test_img); } @Override protected void onDestroy() { super.onDestroy(); } @Override public void onGetImgaeDone(Bitmap bm) { mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_IMG, bm)); } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if(msg.what==MSG_UPDATE_IMG){ if(msg.obj instanceof Bitmap){
Bitmap bm = (Bitmap)msg.obj; mImg.setImageBitmap(bm); } } super.handleMessage(msg); } }; }