简述:
为了了解Android对于图片本地缓存和打开并展现的过程,设计了如下流程,
通过HTTP请求,得到图片文件之后,存储到本地。点击事件之后获取该图片文件,并展现在控件里。
知识点:
一. HTTP文件请求
二. 本地文件的存储
三. 本地文件打开和展现
实现过程:
1. 首先实现的是从server上获取图片流,转换之后显示到UI中,实现方式调用Drawable的CreateFromStream方法
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btn:
Log.i(TAG, "now get image !");
new Thread(){
public void run() {
Log.i(TAG, "run !");
String url = "http://192.168.0.199:8080/FileServer/fetch?id=idxxx";
byte[] imgBytes = HttpUtil.getFileByteArray(url);
if( imgBytes!=null ){
Message msg = handler.obtainMessage(IMAGE_SUCCESS, imgBytes);
handler.sendMessage(msg);
Log.i(TAG, "" + imgBytes.length);
}else{
handler.sendEmptyMessage(IMAGE_FAILURE);
}
};
}.start();
break;
default:
break;
}
}
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case IMAGE_FAILURE:
Toast.makeText(context, "Image Failure", 1000);
break;
case IMAGE_SUCCESS:
Log.i(TAG, "success");
byte[] result = (byte[]) msg.obj;
ByteArrayInputStream bais = new ByteArrayInputStream(result);
Drawable img = Drawable.createFromStream(bais, "image");
iv.setImageDrawable(img);
}
}
};
示意图:
下面使用bitmap来做展现,效果图相同
byte[] result = (byte[]) msg.obj;
Bitmap bMap = BitmapFactory.decodeByteArray(result, 0, result.length);
iv.setImageBitmap(bMap);
代码:
package com.anialy.testproj;
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.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.anialy.util.HttpUtil;
public class MainActivity extends Activity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private static final int IMAGE_FAILURE = 0x0;
private static final int IMAGE_SUCCESS = 0x1;
private Activity context;
/**
* 定义控件
*/
private Button btn;
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
setContentView(R.layout.activity_main);
initWidgets();
}
private void initWidgets(){
btn = (Button) findViewById(R.id.btn);
iv = (ImageView) findViewById(R.id.iv);
//设置监听
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btn:
Log.i(TAG, "now get image !");
new Thread(){
public void run() {
Log.i(TAG, "run !");
String url = "http://192.168.0.199:8080/Server/fetch?id=myImage";
byte[] imgBytes = HttpUtil.getFileByteArray(url);
if( imgBytes!=null ){
Message msg = handler.obtainMessage(IMAGE_SUCCESS, imgBytes);
handler.sendMessage(msg);
Log.i(TAG, "" + imgBytes.length);
}else{
handler.sendEmptyMessage(IMAGE_FAILURE);
}
};
}.start();
break;
default:
break;
}
}
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case IMAGE_FAILURE:
Toast.makeText(context, "Image Failure", 1000);
break;
case IMAGE_SUCCESS:
Log.i(TAG, "success");
byte[] result = (byte[]) msg.obj;
Bitmap bMap = BitmapFactory.decodeByteArray(result, 0, result.length);
iv.setImageBitmap(bMap);
}
}
};
}
2. 网络上的图片流现在可以转为本地的Drawable或者是Bitmap,并在UI上显示,
之后要做的就是本地文件的存储
首先实现的是借助sd卡存储
第一种,手机ROM存储
package com.anialy.testproj;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.anialy.util.HttpUtil;
public class MainActivity extends Activity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private static final int IMAGE_FAILURE = 0x0;
private static final int IMAGE_SUCCESS = 0x1;
private Activity context;
/**
* 定义控件
*/
private Button btn;
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
setContentView(R.layout.activity_main);
initWidgets();
}
private void initWidgets(){
btn = (Button) findViewById(R.id.btn);
iv = (ImageView) findViewById(R.id.iv);
//设置监听
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btn:
Log.i(TAG, "now get image !");
new Thread(){
public void run() {
Log.i(TAG, "run !");
// 检测sd卡是否插入
Log.i(TAG, "sd in !");
String url = "http://192.168.2.199:8080/Server/fetchImage?id=imageId";
InputStream is = HttpUtil.getInputStreambyURL(url);
FileOutputStream fos = null;
try {
fos = openFileOutput("image0", Context.MODE_PRIVATE);;
byte[] bytes = new byte[1024];
int len = 0;
while( (len = is.read(bytes))!=-1 ){
fos.write(bytes, 0, len);
}
fos.flush();
fos.close();
is.close();
} catch (FileNotFoundException e) {
Log.i(TAG, e.toString());
} catch (IOException e) {
Log.i(TAG, e.toString());
e.printStackTrace();
}
handler.sendEmptyMessage(IMAGE_SUCCESS);
};
}.start();
break;
default:
break;
}
}
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case IMAGE_FAILURE:
Toast.makeText(context, "Image Failure", 1000);
break;
case IMAGE_SUCCESS:
Log.i(TAG, "success");
FileInputStream fis = null;
byte[] bytes = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len;
try {
fis = openFileInput("image0");
while( (len=fis.read(bytes))!=-1 ){
baos.write(bytes, 0, len);
}
} catch (FileNotFoundException e) {
Log.i(TAG, e.toString());
} catch (IOException e) {
Log.i(TAG, e.toString());
}
Bitmap bMap = BitmapFactory.decodeByteArray(
baos.toByteArray(), 0, baos.toByteArray().length);
iv.setImageBitmap(bMap);
try {
baos.flush();
baos.close();
} catch (IOException e) {
Log.i(TAG, e.toString());
}
}
}
};
}
第二种,打开的文件对象是sd卡上的
package com.anialy.testproj;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.anialy.util.HttpUtil;
public class MainActivity extends Activity implements View.OnClickListener {
private static final String TAG = "MainActivity";
private static final int IMAGE_FAILURE = 0x0;
private static final int IMAGE_SUCCESS = 0x1;
private Activity context;
/**
* 定义控件
*/
private Button btn;
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
setContentView(R.layout.activity_main);
initWidgets();
}
private void initWidgets(){
btn = (Button) findViewById(R.id.btn);
iv = (ImageView) findViewById(R.id.iv);
//设置监听
btn.setOnClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btn:
Log.i(TAG, "now get image !");
new Thread(){
public void run() {
Log.i(TAG, "run !");
// 检测sd卡是否插入
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED)) {
Log.i(TAG, "sd in !");
String url = "http://192.168.2.199:8080/Server/fetchImage?id=imageID";
InputStream is = HttpUtil.getInputStreambyURL(url);
File sdCardDir = Environment.getExternalStorageDirectory();
File imgFile = new File(sdCardDir, "image");
if( !imgFile.exists() ){
imgFile.mkdir();
}
File img = new File(imgFile, "xxx");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(img);
byte[] bytes = new byte[1024];
int len = 0;
while( (len = is.read(bytes))!=-1 ){
fos.write(bytes, 0, len);
}
fos.flush();
fos.close();
is.close();
} catch (FileNotFoundException e) {
Log.i(TAG, e.toString());
} catch (IOException e) {
Log.i(TAG, e.toString());
e.printStackTrace();
}
handler.sendEmptyMessage(IMAGE_SUCCESS);
} else {
Log.i(TAG, "sd not-existence");
handler.sendEmptyMessage(IMAGE_FAILURE);
}
};
}.start();
break;
default:
break;
}
}
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case IMAGE_FAILURE:
Toast.makeText(context, "Image Failure", 1000);
break;
case IMAGE_SUCCESS:
Log.i(TAG, "success");
FileInputStream fis = null;
byte[] bytes = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len;
try {
File sdCardDir = Environment.getExternalStorageDirectory();
File imgFile = new File(sdCardDir, "image/xxx");
fis = new FileInputStream(imgFile);
while( (len=fis.read(bytes))!=-1 ){
baos.write(bytes, 0, len);
}
} catch (FileNotFoundException e) {
Log.i(TAG, e.toString());
} catch (IOException e) {
Log.i(TAG, e.toString());
}
Bitmap bMap = BitmapFactory.decodeByteArray(
baos.toByteArray(), 0, baos.toByteArray().length);
iv.setImageBitmap(bMap);
try {
baos.flush();
baos.close();
} catch (IOException e) {
Log.i(TAG, e.toString());
}
}
}
};
}
效果图相同
此外是网络流的请求的工具类实现
HttpUtil.java
package com.anialy.util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class HttpUtil {
public static byte[] getFileByteArrayByURL(String url){
URL urlDownload;
byte[] result = null;
try {
urlDownload = new URL(url);
HttpURLConnection connection = (HttpURLConnection)urlDownload.openConnection();
connection.connect();
InputStream is = connection.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len = 0;
while((len = is.read(bytes)) != -1){
baos.write(bytes, 0, len);
}
result = baos.toByteArray();
baos.flush();
baos.close();
is.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public static InputStream getInputStreambyURL(String url){
URL urlDownload;
InputStream is = null;
try {
urlDownload = new URL(url);
HttpURLConnection connection = (HttpURLConnection)urlDownload.openConnection();
connection.connect();
is = connection.getInputStream();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return is;
}
}