在此之前,我写过一篇关于在百度地图上异步加载头像的解决方案,但随着用户量的增加,之前的策略明显有缺陷,比如之前方法对网络要求教高,常有测试人员和我说头像加载缓慢,并且有时候图片加载错位。后来,我想了很久。将问题回到原点,重新设计了一套解决方案。
问题:地图异步加载从服务器获取的图片,并以自定义圆形头像显示在地图
解决思路:
1、子线程获取所有头像的url
2、通过ImageLoader异步获取所有bitmap(这儿说一点,因为百度地图的marker不支持异步加载图片,所有marker里的icon都是ok的图片,所以我们要事先将所有bitmap获取到本地)
3、循环将头像作为icon的参数构造marker,并将marker添加到地图
首先从服务器获取附近所有用户发布的任务,根据表关系可以获取到所有头像url,存入HashMap中,将获取到的url通过ImageLoader异步加载到bitmap,在ImageLoader的回调中将头像保存起来。最后循环将头像显示在地图上即可,详细过程可参考以下核心代码,有不明白的课留言。
/**
* 查找附近的服务
*/
public void findTaskNearBy() {
taskNearBy.clear();
// initMarker();
new Thread(new Runnable() {
@Override
public void run() {
AVQuery<AVObject> query = new AVQuery<>("Task");
// 查找附近10km内的任务
query.include("pub_user.userAvater");
query.whereWithinKilometers("geoPoint", mMyPoint, 10);
// query.whereNotEqualTo("publisherName", mUsername);
try {
List<AVObject> taskList = query.find();
Task taskBean = null;
for (AVObject task : taskList) {
taskBean = new Task();
taskBean.setPublisherName(task
.getString("publisherName"));
taskBean.setEndTime(task.getString("endTime"));
taskBean.setPrice(task.getString("price"));
taskBean.setTheme(task.getString("theme"));
taskBean.setTaskDescription(task
.getString("TaskDescription"));
taskBean.setLatitude(task.getAVGeoPoint("geoPoint")
.getLatitude());
taskBean.setLongitude(task.getAVGeoPoint("geoPoint")
.getLongitude());
taskBean.setLocation(task.getString("location"));
taskBean.setType(task.getString("service_type"));
taskBean.setAccepted(task.getBoolean("isAccepted"));
taskBean.setAccomplished(task
.getBoolean("isAccomplished"));
taskBean.setPub_user(task.getAVUser("pub_user"));
taskNearBy.add(taskBean);
// 获取头像url
AVUser user = (AVUser) task.getAVUser("pub_user");
if (null != user&&null!=user.getAVFile("userAvater")) {
String avaterUrl = user.getAVFile("userAvater")
.getUrl();
hash_avaterUrls.put(taskBean.getPublisherName(),
avaterUrl);
}
}
//showAllMarkersOnMap();
//loadAllAvaters();
} catch (AVException e) {
e.printStackTrace();
}
Log.i("TAG", "taskNearBy大小为:"+taskNearBy.size());
Log.i("TAG", "hash_avaterUrls大小为:"+hash_avaterUrls.size());
for(int i=0;i<taskNearBy.size();i++){
String name=taskNearBy.get(i).getPublisherName();
downloadAvaterBitmaps(name, hash_avaterUrls.get(name));
}
}
}).start();
}
/**
*
* @param username 用户名
* @param url 头像url
*/
public void downloadAvaterBitmaps(final String username,final String url){
DisplayImageOptions option = new DisplayImageOptions.Builder()
.showImageForEmptyUri(R.drawable.default_load)// 设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.drawable.default_load)// 设置图片加载或解码过程中发生错误显示的图片
.bitmapConfig(Bitmap.Config.RGB_565).build();
//String urlString=hash_avaterUrls.get(taskNearBy.get(i).getPublisherName());
ImageLoader.getInstance().loadImage(url, option, new ImageLoadingListener() {
@Override
public void onLoadingStarted(String arg0, View arg1) {
}
@Override
public void onLoadingFailed(String arg0, View arg1, FailReason arg2) {
}
@Override
public void onLoadingComplete(String arg0, View arg1, Bitmap arg2) {
bitMaps.put(username, arg2);
Log.i("TAG", "downloadAvaterBitmaps");
if(bitMaps.size()==taskNearBy.size()){
showAllMarkersOnMap();
Log.i("TAG", "加载完成");
}
}
@Override
public void onLoadingCancelled(String arg0, View arg1) {
}
});
}
/**
* 将所有任务以发布人头像显示在地图上
*/
private void showAllMarkersOnMap() {
mBaiduMap.clear();
Bitmap bitmap = null;
Marker marker = null;
LatLng latLng = null;
OverlayOptions options;
for (int i = 0; i < taskNearBy.size(); i++) {
initMarker();
latLng = new LatLng(taskNearBy.get(i).getLatitude(), taskNearBy
.get(i).getLongitude());
if (bitMaps.get(taskNearBy.get(i).getPublisherName()) != null) {
bitmap = Bitmap.createBitmap(bitMaps.get(taskNearBy.get(i)
.getPublisherName()));
} else {
bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.default_user_img);
}
circleImageView.setImageBitmap(bitmap);
circleImageView.setImageAlpha(0);
mMarkDescriptor=BitmapDescriptorFactory.fromView(circleImageView);
if(mMarkDescriptor!=null){
options = new MarkerOptions().position(latLng)
.icon(mMarkDescriptor).zIndex(5);
marker = (Marker) mBaiduMap.addOverlay(options);
}else {
Log.i("TAG", "加载头像出错");
}
Bundle arg0 = new Bundle();
arg0.putSerializable("info", taskNearBy.get(i));
marker.setExtraInfo(arg0);
}
MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
mBaiduMap.setMapStatus(msu);
}