本文的主要目的是:把访问网络这一步骤,封装在一个类里面,然后在主函数回调这个类里面的接口,即可做到完成访问网络下载图片,这样使我们不用每访问一次网络就写一大堆代码,只要把回调的接口new出来就OK了,下面贴代码 :
package com.example.test05;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.example.test05.BaseClient.NetHandler;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
private Button bt1;
//图片的 URL
String url="http://imgsrc.baidu.com/forum/pic/item/c7a786025aafa40feb7c6e07ae64034f79f0190d.jpg";
//new 出这个工具类
private BaseClient client=new BaseClient();
//main.xml上的三个控件
private ProgressBar pb1;
private ImageView iv1;
private TextView tv1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//控件初始化
iv1=(ImageView) findViewById(R.id.iv1);
pb1=(ProgressBar) findViewById(R.id.pb1);
bt1=(Button) findViewById(R.id.bt1);
tv1=(TextView) findViewById(R.id.tv1);
//点击按钮,开始访问网络
bt1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
//执行访问网络方法,把url传进去
client.get(url);
//回调
client.setOnNetListener(new NetHandler() {
//downLoadSize是当前下载的长度,maxSize是这个文件的总长度
@Override
public void onProgess(int downLoadSize,int maxSize) {
// TODO Auto-generated method stub
pb1.setProgress(downLoadSize*100/maxSize);
tv1.setText(downLoadSize*100/maxSize+"/"+"100");
}
@Override
public void onSuccess(byte[] result) {
// TODO Auto-generated method stub
//把图片显示出来
Bitmap bitmap=BitmapFactory.decodeByteArray(result, 0, result.length);
iv1.setImageBitmap(bitmap);
}
@Override
public void onFailure(Object exception) {
// TODO Auto-generated method stub
}
});
}
});
}
}
BaseClient工具类:
package com.example.test05;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.os.Handler;
import android.os.Message;
public class BaseClient {
//请求失败静态常量
private static final int REQ_FAILED=0;
//请求成功静态常量
private static final int REQ_SUCCESS=1;
//请求的进度静态常量
private static final int REQ_PROGRESS=2;
//图片的最大长度
private int maxLength;
//当前下载的长度
private int progress;
//构造出一个接口对象
private NetHandler mNetHandler;
private Handler mHandler=new Handler(){
public void handleMessage(android.os.Message msg) {
switch(msg.what){
case REQ_SUCCESS:
byte []result=(byte[]) msg.obj;
onSuccess(result);
break;
case REQ_FAILED:
String e=(String) msg.obj;
onFailure(e.toString());
break;
case REQ_PROGRESS:
OnProgress(progress,maxLength);
break;
}
};
};
public void get(final String path){
//开启一个线程去访问网络
new Thread(){
public void run() {
try {
URL url=new URL(path);
HttpURLConnection con=(HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setReadTimeout(3000);
con.setConnectTimeout(3000);
int code=con.getResponseCode();
if(code==200){
//得到这个图片的输入流
InputStream is=con.getInputStream();
//得到这个输入流的总长度
maxLength=con.getContentLength();
byte buffer[]=new byte[1024];
ByteArrayOutputStream bos=new ByteArrayOutputStream();
progress=0;
int len=0;
while((len=is.read(buffer))>0){
//实现进度的增加
progress+=len;
//发送消息去通知主线程更新数据
Message message=new Message();
message.what=REQ_PROGRESS;
mHandler.sendMessage(message);
bos.write(buffer, 0, len);
}
//下载成功,把byte数组发过去
byte res[]=bos.toByteArray();
Message message=new Message();
message.obj=res;
message.what=REQ_SUCCESS;
mHandler.sendMessage(message);
}
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Message message=new Message();
message.obj=e;
message.what=REQ_FAILED;
mHandler.sendMessage(message);
}
};
}.start();
}
public void onSuccess(byte[] result){
mNetHandler.onSuccess(result);
}
public void onFailure(Object object){
mNetHandler.onFailure(object);
}
public void OnProgress(int downloadSize,int maxSize){
mNetHandler.onProgess(downloadSize,maxSize);
}
public void setOnNetListener(NetHandler l){
mNetHandler=l;
}
//接口
public interface NetHandler{
public void onSuccess(byte[] result);
public void onFailure(Object exception);
public void onProgess(int downloadSize,int maxSize);
}
}
main.xml代码:
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.test05.MainActivity" >
<Button
android:id="@+id/bt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="访问网络获取图片" />
<ImageView
android:id="@+id/iv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="@drawable/no_pictures" />
<ProgressBar
android:id="@+id/pb1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/iv1"
android:layout_centerHorizontal="true"
android:layout_marginTop="24dp" />
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/pb1"
android:layout_below="@+id/pb1"
android:text="TextView" />
</RelativeLayout>
效果图:
总结:回调接口这种设计思想刚开始学的时候给人感觉就是很巧妙,而当实际运用到程序里,会节省大量敲代码的时间,这种设计模式还是非常实用的.