I'm adding markers to my map from a url using the Picasso library
As a marker isn't an ImageView I tried to use a Target instead
for(int x =0; x < mapIcon_url.length; x++){
Picasso.with(getActivity()).load(mapIcon_url[x]).resize(marker_size, marker_size+15).into(new Target() {
@Override
public void onSuccess(Bitmap b) {
bitmapMarker = BitmapDescriptorFactory.fromBitmap(b);
//create marker option
if(b != null)
markerOptions = new MarkerOptions().position(marker_position).icon(bitmapMarker));
else
markerOptions = new MarkerOptions().position(marker_position).icon(BitmapDescriptorFactory.fromResource(R.drawable.placeholder_pin)).snippet(String.valueOf(x));
marker = map.addMarker(markerOptions);
}
@Override
public void onError() {
//create marker option
markerOptions = new MarkerOptions().position(marker_position).icon(BitmapDescriptorFactory.fromResource(R.drawable.placeholder_pin)).snippet(String.valueOf(x));
marker = map.addMarker(markerOptions);
}
});
}
I'm doing this in a loop to add about 20 markers but I find that on first run of the code only 5 or 7 markers are added so I've switched to using the lib and an AsyncTask like this.
for(int x =0; x < mapIcon_url.length; x++){
new AddMarker().execute(mapIcon_url[x]);
}
public class AddMarker extends AsyncTask<String, Integer, BitmapDescriptor> {
BitmapDescriptor bitmapMarker1;
VenueDetails myVenue;
@Override
protected BitmapDescriptor doInBackground(String... url) {
myUrl = url[0];
try {
bitmapMarker1 = BitmapDescriptorFactory.fromBitmap(Picasso.with(getActivity()).load(myUrl).resize(marker_size, marker_size+15).get());
} catch (IOException e) {
e.printStackTrace();
}
return bitmapMarker1;
}
protected void onPostExecute(BitmapDescriptor icon) {
try {
map.addMarker(new MarkerOptions().position(marker_position).icon(icon)));
} catch (Exception e) {
e.printStackTrace();
}
}
}
However I'm a bit worried this method could give me some issues when I have alot of markers say about 100. My question would be is this the best way to do this and if not what other options can I try.
You have to keep a reference for each Target, otherwise the system automatically releases them when the garbage collector is invoked.
So, the better solution is add each Target to a HashSet and then in onBitmapLoaded() and onBitmapFailed methods from Target, remove the Target itself from the set.
Thank you for the suggestion, now my code work perfectly. Below the pieces of code that implement your suggestion.
[...]//Global var
private Set<PoiTarget> poiTargets = new HashSet<PoiTarget>();
[...]
private void somewhere(){
PoiTarget pt;
for(Item item: data) {
m = map.addMarker(new MarkerOptions()
.position(new LatLng(item.latitude, item.longitude))
.title(item.title));
pt = new PoiTarget(m);
poiTargets.add(pt);
Picasso.with(context)
.load(mapImageURLString)
.into(pt);
}
}
[...]
//--------------------------------------------------------
// Inner class
//--------------------------------------------------------
class PoiTarget implements Target{
private Marker m;
public PoiTarget(Marker m) { this.m = m; }
@Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
m.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap));
poiTargets.remove(this);
Tools.msg(" @+ Set bitmap for "+m.getTitle()+" PT size: #"+poiTargets.size());
}
@Override public void onBitmapFailed(Drawable errorDrawable) {
Tools.msg(" @+ [ERROR] Don't set bitmap for "+m.getTitle());
poiTargets.remove(this);
}
@Override public void onPrepareLoad(Drawable placeHolderDrawable) {
}
}
You have to keep a reference for each Target
, otherwise the system automatically releases them when the garbage collector is invoked.
So, the better solution is add each Target to a HashSet
and then in onBitmapLoaded()
and onBitmapFailed
methods from Target, remove the Target itself from the set.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With