1.设计
2.java代码
下载网络资源工具类
public class HttpUtils {
// 获取网络上的json字符串
// 输入String(url)
// 返回String(jsonStr)
public static String getHttpStr(String url) {
HttpClient httpClient = new DefaultHttpClient(); // Http客户端
HttpGet httpGet = new HttpGet(url); // GET请求
try {
HttpResponse response = httpClient.execute(httpGet); // 发起请求
if(response.getStatusLine().getStatusCode() == 200) {
// 200表示连接成功
HttpEntity entity = response.getEntity(); // Http实体(有效信息)
InputStream is = entity.getContent(); // 通过实体获取网络资源的内容(InputStream)
// 开始下载数据
ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 输出缓冲流(把全部的网络资源保存起来)
byte[] buffer = new byte[1024]; // 缓冲区
int ret;
while(true) {
ret = is.read(buffer);
if(ret < 0) {
break;
}
baos.write(buffer, 0, buffer.length); // 每次把缓冲区的内容写入换冲流(缓冲区的内容每次都会不同)
}
return baos.toString(); // boas中的内容就是我们需要的数据了
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// 获取网络上的图片
// 输入String(url)
// 返回Bitmap(图片)
public static Bitmap getHttpBitmap(String url) {
HttpClient httpClient = new DefaultHttpClient(); // Http客户端
HttpGet httpGet = new HttpGet(url); // GET请求
try {
HttpResponse response = httpClient.execute(httpGet); // 发起请求
if(response.getStatusLine().getStatusCode() == 200) {
// 200表示连接成功
HttpEntity entity = response.getEntity(); // Http实体(有效信息)
InputStream is = entity.getContent(); // 通过实体获取网络资源的内容(InputStream)
// 开始下载数据
ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 输出缓冲流(把全部的网络资源保存起来)
byte[] buffer = new byte[1024]; // 缓冲区
int ret;
while(true) { // 屌丝的代码 大神请忽略
ret = is.read(buffer);
if(ret < 0) {
break;
}
baos.write(buffer, 0, buffer.length); // 每次把缓冲区的内容写入换冲流(缓冲区的内容每次都会不同)
}
byte[] byteArr = baos.toByteArray(); // boas中的内容就是我们需要的数据了 先转换成字节数组
// 把字节数组的内容转换成图片
return BitmapFactory.decodeByteArray(byteArr, 0, byteArr.length);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
解析JSON工具类
public class JSONUtils {
// 格式为
// {"person":[{"address":"ServerForJSON/frjj.jpg","id":1001,"name":"Rose"},
// {"address":"ServerForJSON/frjj2.jpg","id":1002,"name":"Jack"}]}
public static List<Person> parsePersonJSONStr(String jsonStr) {
try {
List<Person> list = new ArrayList<Person>();
// 最外层的{}(JSONObject) 表示"所有人"
JSONObject jsonObject = new JSONObject(jsonStr);
// 根据key="person"获取value(JSONArray)
JSONArray jsonArray = (JSONArray) jsonObject.get("person");
// 遍历jsonArray中每一个人 (JSONObject)
for(int i = 0; i < jsonArray.length(); i++) {
// 获取每个人的json对象
JSONObject jsonObject2 = (JSONObject) jsonArray.get(i);
// 对于每一个人 分别获取address、id、name
String address = (String) jsonObject2.get("address");
int id = (Integer) jsonObject2.get("id");
String name = (String) jsonObject2.get("name");
// 通过地址下载并生成图片
Bitmap bitmap = HttpUtils.getHttpBitmap(MainActivity.URL+address);
// 生成Person的对象
Person person = new Person(id, name, address, bitmap);
list.add(person); // 添加到list列表中
}
return list; // 返回人的列表
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
自定义适配器
public class MyAdapter extends BaseAdapter {
private List<Person> list;
private Context context;
// 通过构造器传递参数 List<Person>、Context
public MyAdapter(List<Person> list, Context context) {
this.list = list;
this.context = context;
}
// 获取数据的大小数量(List<Person>)
@Override
public int getCount() {
return list.size();
}
// 根据下标获取列表中具体的数据
@Override
public Object getItem(int position) {
return list.get(position);
}
// 根据下标获取ID(下标)
@Override
public long getItemId(int position) {
return position;
}
// 根据下标获取对应的视图
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
ViewHolder holder = null;
if(convertView == null) {
// 1. 首次加载时 没有缓冲的view 只能创建View
LayoutInflater inflater = LayoutInflater.from(context);
view = inflater.inflate(R.layout.item, null);
// 2. 创建holder 并在view中查找holder中的视图(查找是很耗时间的)
holder = new ViewHolder();
holder.image = (ImageView) view.findViewById(R.id.image); // 图片
holder.textview1 = (TextView) view.findViewById(R.id.textview1); // id
holder.textview2 = (TextView) view.findViewById(R.id.textview2); // 姓名
// 3. 绑定view和holder
view.setTag(holder);
} else {
// 1. 后面加载时 已经有缓存的view 可复用
view = convertView;
// 2. 直接拿来使用
holder = (ViewHolder) view.getTag();
}
// 4. 给image、textview1、textview2赋值
Person person = list.get(position); // 具体的人
Bitmap bitmap = person.getBitmap(); // 得到TA的图片
holder.image.setImageBitmap(bitmap);
int id = person.getId(); // 得到TA的id
holder.textview1.setText(id+"");
String name = person.getName(); // 得到TA的name
holder.textview2.setText(name);
// 5. 返回view
return view;
}
// ViewHolder内部类 把视图包装在一起
public class ViewHolder {
public ImageView image;// 图片
public TextView textview1; // id
public TextView textview2; // 姓名
}
}
异步任务类
public class MyTask extends AsyncTask<String, Void, List<Person>> {
private Context context; // 上下文
private ListView listview; // 列表视图
// 通过构造器传递参数 context、listview
public MyTask(Context context, ListView listview) {
this.context = context;
this.listview = listview;
}
// 执行下载、解析json字符串的功能(子线程)
@Override
protected List<Person> doInBackground(String... params) {
String url = params[0]; // 获得输入的url
// 通过url下载json字符串
String jsonStr = HttpUtils.getHttpStr(url);
// 通过json字符串获取人的列表
List<Person> list = JSONUtils.parsePersonJSONStr(jsonStr);
// 调试中……测试成功
Log.i("MyTask", jsonStr);
for(Person p : list) {
Log.i("MyTask", p.toString());
}
return list;
}
// 执行后台操作前的准备步骤(主)(显示对话框)
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
// 执行后台操作后的处理工作(主)(取消对话框、显示结果)
@Override
protected void onPostExecute(List<Person> result) {
// 到这里才开始启动adapter
// 因为到这里 才能真正得到数据
MyAdapter adapter = new MyAdapter(result, context);
listview.setAdapter(adapter); // 把数据设置到listview上
super.onPostExecute(result);
}
}
对象类
public class Person {
private int id;
private String name; // 姓名
private String address; // 图片地址
private Bitmap bitmap; // 图片
// 构造器
public Person() {}
public Person(int id, String name, String address, Bitmap bitmap) {
super();
this.id = id;
this.name = name;
this.address = address;
this.bitmap = bitmap;
}
// getter setter
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Bitmap getBitmap() {
return bitmap;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
// toString
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", address=" + address + ", bitmap=" + bitmap + "]";
}
}
MainActivity类
public class MainActivity extends Activity {
// 地址常量
// 下载json字符串时使用:http://10.16.154.26:8080/ServerForJSON/JsonServlet
// URL+PATH
// 下载图片时使用:http://10.16.154.26:8080/ServerForJSON/frjj.jpg
// URL+address
public static final String URL = "http://10.16.154.26:8080/";
public static final String PATH = "ServerForJSON/JsonServlet";
private ListView listview;
private ImageView imageview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 找出activity_main中的listview
listview = (ListView) findViewById(R.id.listview);
// 设置当listview中没有数据的时候 显示空白的图片
imageview = (ImageView) findViewById(R.id.imageview);
listview.setEmptyView(imageview);
// 创建异步任务类并启动执行子线程
MyTask task = new MyTask(MainActivity.this, listview);
task.execute(URL+PATH);
}
}
3.UML流程图
4.效果图