在Android開發中,經常需要從后台服務器下載圖片進行顯示。雖然有很多現成的開源框架使用,給定一個url,進行一些配置后,直接就能加載圖片顯示,緩存都做好了。但是有的場景,例如涉及安全、隱私的場合,不能直接拿一個公開的url使用,還是需要通過原始數據流的方法來獲取圖片。
通過請求參數,進行一些驗證,能提高安全性。這里以最簡單的IO流為例,沒有涉及到圖片緩存。好,廢話不多說,直接上代碼:
package com.example.downloadpictest;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
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.ImageView;
public class MainActivity extends Activity {
private ImageView ivImg;
private Button btnDownload;
private Bitmap img;
private ImageHandler imgHandler = new ImageHandler();
//測試Url
private String url = "http://192.168.42.193:8080/DownloadPicTest/servlet/DownloadServlet";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ivImg = (ImageView) findViewById(R.id.ivImg);
btnDownload = (Button) findViewById(R.id.btnDownload);
//點擊按鈕開始下載
btnDownload.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
downloadImg();
}
});
}
/** * 異步從服務器加載圖片數據 */
private void downloadImg(){
new Thread(new Runnable() {
@Override
public void run() {
Bitmap img = getImg();
Message msg = imgHandler.obtainMessage();
msg.what = 0;
msg.obj = img;
imgHandler.sendMessage(msg);
}
}).start();
}
/** * 異步線程請求到的圖片數據,利用Handler,在主線程中顯示 */
class ImageHandler extends Handler{
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
img = (Bitmap)msg.obj;
if(img != null){
ivImg.setImageBitmap(img);
}
break;
default:
break;
}
}
}
/** * 從服務器讀取圖片流數據,並轉換為Bitmap格式 * @return Bitmap */
private Bitmap getImg(){
Bitmap img = null;
try {
URL imgUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imgUrl.openConnection();
conn.setRequestMethod("POST");
conn.setConnectTimeout(1000 * 6);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Charset", "UTF-8");
conn.connect();
//輸出流寫參數
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
String param = getParam();
dos.writeBytes(param);
dos.flush();
dos.close();
int resultCode = conn.getResponseCode();
if(HttpURLConnection.HTTP_OK == resultCode){
InputStream is = conn.getInputStream();
img = BitmapFactory.decodeStream(is);
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return img;
}
/** * 測試參數 * @return */
private String getParam(){
JSONObject jsObj = new JSONObject();
try {
jsObj.put("picFormat", "jpg");
jsObj.put("testParam", "9527");
} catch (JSONException e) {
e.printStackTrace();
}
return jsObj.toString();
}
}
代碼很好理解,就不做過多說明了。注意不要忘了在Manifest中配置網絡權限
<uses-permission android:name="android.permission.INTERNET"/>
效果圖如下
至於服務器響應圖片數據流,可以參考我自己寫的一個簡單示例: http://blog.csdn.net/ceovip/article/details/79100451