Android 毕加索在第一次应用程序启动时未加载图像
我用Android 毕加索在第一次应用程序启动时未加载图像,android,google-maps,android-asynctask,google-maps-markers,picasso,Android,Google Maps,Android Asynctask,Google Maps Markers,Picasso,我用谷歌地图进行活动,我向服务器发送请求,解析JSON响应并添加标记,使用毕加索加载图标 问题 接下来的问题是:当我关闭应用程序并再次打开它时,数据加载(URL也加载良好),标记添加到谷歌地图上,但它们有默认图标,毕加索不会加载新图标(onBitmapLoaded()未调用)。当我完成活动并再次启动它(不关闭应用程序)时,新标记的图标也会加载 我对毕加索目标的实现: public class PicassoMarker implements Target { private static
谷歌地图进行活动
,我向服务器发送请求,解析JSON响应并添加标记
,使用毕加索加载图标
问题
接下来的问题是:当我关闭应用程序并再次打开它时,数据加载(URL也加载良好),标记添加到谷歌地图上,但它们有默认图标,毕加索不会加载新图标(onBitmapLoaded()未调用)。当我完成活动
并再次启动它(不关闭应用程序)时,新标记的图标也会加载
我对毕加索目标的实现:
public class PicassoMarker implements Target {
private static final String TAG = "PicassoMarker";
private Marker marker;
private LoadingCallBacks loadingCallBacks;
public PicassoMarker(Marker marker) {
this.marker = marker;
}
public PicassoMarker(Marker marker, LoadingCallBacks loadingCallBacks) {
this.marker = marker;
this.loadingCallBacks = loadingCallBacks;
}
@Override
public int hashCode() {
return marker.hashCode();
}
@Override
public boolean equals(Object o) {
if (o instanceof PicassoMarker) {
Marker marker = ((PicassoMarker) o).marker;
return this.marker.equals(marker);
} else {
return false;
}
}
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
marker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
Log.d(TAG, "onBitmapLoaded() -> " +
"\nBitmap:" +
"\n\twidth: " + bitmap.getWidth() +
"\n\theight: " + bitmap.getHeight() /*+
"\nCanvas:" +
"\n\twidth: " + resultBitmap.getWidth() +
"\n\theight: " + resultBitmap.getHeight()*/
);
if (loadingCallBacks != null) {
loadingCallBacks.onLoaded(bitmap);
}
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.e(TAG, "onBitmapFailed()");
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
Log.d(TAG, "onPrepareLoad()");
}
public void setLoadingCallBacks(LoadingCallBacks loadingCallBacks) {
this.loadingCallBacks = loadingCallBacks;
}
public interface LoadingCallBacks {
void onLoaded(Bitmap bitmap);
}
}
以及我的异步任务
,用于发送请求和添加标记
:
new AsyncTask<String, Void, ArrayList<MarkerDataModel>>() {
private ArrayList<MarkerDataModel> markerDataModels = new ArrayList<>();
@Override
protected void onPreExecute() {
}
@Override
protected ArrayList<MarkerDataModel> doInBackground(String... params) {
// Parsing JSON ...
return markerDataModels;
}
@Override
protected void onPostExecute(ArrayList<MarkerDataModel> markerDataModels) {
if (markerDataModels != null && markerDataModels.size() != 0) {
MarkerDataModel markerDataModel;
for (int i = 0; i < markerDataModels.size(); i++) {
markerDataModel = markerDataModels.get(i);
Marker marker = googleMap.addMarker(new MarkerOptions()
.position(new LatLng(markerDataModel.getLat(), markerDataModel.getLng()))
.title(markerDataModel.getLabel()));
PicassoMarker picassoMarker picassoMarker = new PicassoMarker(marker);
Picasso.
with(activityContext)
.load(markerDataModel.getIcon())
//.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
//.networkPolicy(NetworkPolicy.NO_CACHE)
.into(picassoMarker);
}
}
}
}.execute("http://example.com");
newasynctask(){
私有ArrayList markerDataModels=新ArrayList();
@凌驾
受保护的void onPreExecute(){
}
@凌驾
受保护的ArrayList doInBackground(字符串…参数){
//正在解析JSON。。。
返回markerDataModels;
}
@凌驾
PostExecute上受保护的void(ArrayList markerDataModels){
if(markerDataModels!=null&&markerDataModels.size()!=0){
MarkerDataModel MarkerDataModel;
对于(int i=0;i
解决方案
我已经解决了这个问题,使用
下面是从网络加载标记'
数据并使用以下命令设置新图标的示例代码:
好处
在TYPE\u PRIMARY
和TYPE\u PEOPLE
之间切换,您可以捕获单击的标记的类型,如下所示:
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
MarkerDataModel markerDataModel = markerAllHashMap.get(marker);
int type;
try {
Log.d(TAG, "onMarkerClick() -> " + markerDataModel.getType());
} catch (Exception ex) {
Log.e(TAG, "onMarkerClick() -> ", ex);
}
try {
type = markerDataModel.getType();
} catch (Exception ex) {
type = -1;
}
switch (type) {
case MarkerDataModel.TYPE_PRIMARY: {
// Do something for TYPE_PRIMARY Marker
break;
}
case MarkerDataModel.TYPE_PEOPLE: {
// Do something for TYPE_PEOPLE Marker (e.g. show user's info)
break;
}
default: {
// Type == -1
marker.showInfoWindow();
break;
}
}
// Animate to center
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder()
.target(marker.getPosition())
.zoom(18)
.build()));
return true;
}
});
解决方案
我已经解决了这个问题,使用
下面是从网络加载标记'
数据并使用以下命令设置新图标的示例代码:
好处
在TYPE\u PRIMARY
和TYPE\u PEOPLE
之间切换,您可以捕获单击的标记的类型,如下所示:
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
MarkerDataModel markerDataModel = markerAllHashMap.get(marker);
int type;
try {
Log.d(TAG, "onMarkerClick() -> " + markerDataModel.getType());
} catch (Exception ex) {
Log.e(TAG, "onMarkerClick() -> ", ex);
}
try {
type = markerDataModel.getType();
} catch (Exception ex) {
type = -1;
}
switch (type) {
case MarkerDataModel.TYPE_PRIMARY: {
// Do something for TYPE_PRIMARY Marker
break;
}
case MarkerDataModel.TYPE_PEOPLE: {
// Do something for TYPE_PEOPLE Marker (e.g. show user's info)
break;
}
default: {
// Type == -1
marker.showInfoWindow();
break;
}
}
// Animate to center
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder()
.target(marker.getPosition())
.zoom(18)
.build()));
return true;
}
});
您是否可以尝试保留对您的PicassoMarker
-Picasso
本身的强引用将只保留一个WeakReference
,因此不会阻止PicassoMarker
被垃圾收集。我不确定这是否解释了为什么你第二次得到这些标记,但这是需要记住的——可能是第一次毕加索的速度太慢了,因为它从网络/光盘(?)加载图标,但是第二次当图标已经在缓存中时速度足够快。@david.mihola,谢谢你的回复!注意,我保留了强引用。我试图阻止缓存检查,当图标从URL加载时,毕加索也加载了它们,但只是第二次。我解决这个问题的办法是滑翔。Glide会在第一次活动开始后加载很棒的图标。您是否可以尝试保留对您的PicassoMarker
-Picasso
本身的强引用将只保留一个WeakReference
,因此不会阻止PicassoMarker
被垃圾收集。我不确定这是否解释了为什么你第二次得到这些标记,但这是需要记住的——可能是第一次毕加索的速度太慢了,因为它从网络/光盘(?)加载图标,但是第二次当图标已经在缓存中时速度足够快。@david.mihola,谢谢你的回复!注意,我保留了强引用。我试图阻止缓存检查,当图标从URL加载时,毕加索也加载了它们,但只是第二次。我解决这个问题的办法是滑翔。第一次活动开始后,Glide加载图标。
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
MarkerDataModel markerDataModel = markerAllHashMap.get(marker);
int type;
try {
Log.d(TAG, "onMarkerClick() -> " + markerDataModel.getType());
} catch (Exception ex) {
Log.e(TAG, "onMarkerClick() -> ", ex);
}
try {
type = markerDataModel.getType();
} catch (Exception ex) {
type = -1;
}
switch (type) {
case MarkerDataModel.TYPE_PRIMARY: {
// Do something for TYPE_PRIMARY Marker
break;
}
case MarkerDataModel.TYPE_PEOPLE: {
// Do something for TYPE_PEOPLE Marker (e.g. show user's info)
break;
}
default: {
// Type == -1
marker.showInfoWindow();
break;
}
}
// Animate to center
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder()
.target(marker.getPosition())
.zoom(18)
.build()));
return true;
}
});