I'm proposing a patch to the PluginMarker.java file that will greatly improve the performance when adding hundreds of markers to the map.
I propose the creation of a createMarkers method (note the plural), which will take the same marker definition as does the currently available createMarker, except for the fact they'll be in an array, therefore allowing the creation of multiple markers with a single over-the-bridge request. Naturally, the callback has to return an array of markers, instead of a single marker.
A private createMarker_ method is to be called by createMarkers. This does not break the current API, and the current createMarker method can be refactored to simply call the private version with its argument in an array.
I have already implemented marker caching and marker pre-loading which on top of that will drastically reduce memory consumption and prevent leaks.
This is where my understanding of this project ends. I don't know what my constraints as a developer are:
I'm seeing fantastic performance with these improvements, I'd really like to contribute them.
Thanks a lot for the help.
The APIs aren't frozen, but I would like to have a heterogeneous environment. iOS and android should be the same level if possible. While the clustering branch resolves most of the memory problems, I would like to incorporate your suggestions, cause not everybody need clustering and the cluster branch has a lot less functionality currently. Once the funding is done, it will be released as own setup, but I would incorporate your edits there, too (ass the clustering can be deactivated by config).
So I'm open for everything. I'm not the lead developer of this plugin. Masashi was, but he dropped it and I took over maintenance and fixed bugs and merged good PRs and incorporated some fixes and functions by myself. So I'm very thankful if someone would help me here.
Can I see the clustering branch? Perhaps I should focus on these changes on that.
Sure. Are you on Skype? We should chat
I've though about this.
A cluster is just _one_ marker where many would be, and it should be the end-user's job to cluster, not the plugin's. The user has the added benefit of being able to pick the clustering method which by the ways begs the question: which are yo using? Are you going to provide multiple? Or perhaps the injection of a clustering interface?
The questions on their own indicate that clustering should be handled outside the plugin. However you answer them, notice the plugin's clustering code will have to _know_ about all the markers the user is creating, plus the clustering method the user wants to use and if the user wants a different clustering method they'll have to bake it in.
Clustering is a black box that takes a bunch of markers and returns one single marker. I would provide clustering as a factory method, to be used as:
var positions = [p1, p2, p3];
var clusterer = new plugin.google.maps.MarkerClusterer(opt_methodName);
var clusterPosition = clusterer.cluster(positions);
Where positions is an array of objects that expose lats and longs via properties or methods (i.e. objects that implement a certain Interface). Remember they're _not_ likely to be the formal Marker objects, since we have not created them yet.
The clusterer will return one single such object exposing a lat-lng pair, which will be used to create the "real" Marker on the map.
This can take advantage of the changes I've made since the user can use the clusterer object to cluster multiple sets of positions outside the plugin then create all Markers (one for each cluster) at once.
We can also have it so that the _user_ injects the clusterer as a function that takes markers and returns marker, both as described above. The user then calls some function with the data that to be clustered, and the function uses the injected clusterer. Once again, this puts into the plugin _data that does not belong there_.
These are just quick thoughts. Perhaps I miss the point entirely. Which way are you going?
Test it:
cordova plugin add https://github.com/mapsplugin/cordova-plugin-googlemaps#clusterer --variable API_KEY_FOR_ANDROID="YOURKEY" --variable API_KEY_FOR_IOS="YOURKEY"
Add following config object to .getMap()
'controller': {
'clustering': true,
'rendering': 'animated',
'algorithm': 'nonHierarchicalDistanceBasedAlgorithm'
}
eg
$rootScope.map = plugin.google.maps.Map.getMap(mapDiv, {
'controls': {
'compass': false,
'myLocationButton': false,
'indoorPicker': false,
'toolbar': false,
'zoom': false
},
'gestures': {
'scroll': true,
'tilt': true,
'rotate': true
},
'controller': {
'clustering': true,
'rendering': 'animated',
'algorithm': 'nonHierarchicalDistanceBasedAlgorithm'
}
});
Edit:
Btw, currently only nonHierarchicalDistanceBasedAlgorithm supported.
As soon as the user has zoomed enough, the real markers will be created.

Same for iOS

A real app to see it in action
https://itunes.apple.com/us/app/a-z-erdgastankstellen/id441500868?mt=8&ls=1
https://play.google.com/store/apps/details?id=de.lf.erdgas&hl=de
Not my app, but its the same codebase which is incorporated.
The Cluster branch works, but it is a bit hacky - and generally this plugin needs a lot refactoring (but I don't have time for that). If you have time and the mood to provide a better clustering solution, I'm open minded to follow your path and spending all donations to you, if you provide a better way for both systems.
Without clustering, I'm using a mix of KML overlay for the bulk of the 'noise' and plain css markers placed over top of the mapdiv together.
the clustering layers (orange markers) are showing wrong numbers. Always double of the real marker-value is shown. Any ideas?
dbesiryan - I'm not supporting something that isn't officially released. This branch is not finished
I'd love to see this feature added. In an app I'm current working on, we have thousands of markers and the client doesn't want clustering.
On ios so far it has been working ok, but on Android it lags out the app as it draws them all (calling add marker for each one inside a foreach)
Deming the shore array to the plugin would be much better
Could I maybe see your app that loads thousands of markers?
I'll set-up a test app with how I'm doing it over the weekend. Sorry it took a while to respond.
@atannus Do you have a fork containing your changes? Have you implemented the bulk marker adding, caching and pre-loading for Android & iOS or only für Android?
No, I made changes directly on the version installed inside my project.
Is this project still being held hostage for funds? This throws me off.
It appears so. There is a clusterer branch but I'm unsure about how complete that is. It would be great if you could commit your changes to your fork (and maybe even open a pull request) if you want to share your work.
I'll see what I can do.
On Thu, Mar 3, 2016 at 10:41 AM, Christian [email protected] wrote:
It appears so. There is a clusterer branch but I'm unsure about how
complete that is. It would be great if you could commit your changes to
your fork (and maybe even open a pull request) if you want to share your
work.—
Reply to this email directly or view it on GitHub
https://github.com/mapsplugin/cordova-plugin-googlemaps/issues/835#issuecomment-191764409
.
André Tannús | Epungo | +55 11 2389-4360
We are a layer
I'm on this now.
Is there a suggested development flow?
IDE?
Should I edit the plugin while installed within a project or
change->(re)install->test?
Thanks.
On Thu, Mar 3, 2016 at 10:44 AM, Andre Tannus andre.[email protected]
wrote:
I'll see what I can do.
On Thu, Mar 3, 2016 at 10:41 AM, Christian [email protected]
wrote:It appears so. There is a clusterer branch but I'm unsure about how
complete that is. It would be great if you could commit your changes to
your fork (and maybe even open a pull request) if you want to share your
work.—
Reply to this email directly or view it on GitHub
https://github.com/mapsplugin/cordova-plugin-googlemaps/issues/835#issuecomment-191764409
.
André Tannús | Epungo | +55 11 2389-4360
We are a layer
André Tannús | Epungo | +55 11 2389-4360
We are a layer
Well calling this a hostage is not very fine. And it's just for the cluster-branch. The cluster branch which is avaiable here "inoffically" was a paid job. It was just improved and cleaned by me. I just was about to give some money back to the code donator. If you guys help to finish this cluster branch, I'm open for it. The branch is not hidden, try it, fix it, improve it.
Is there a suggested development flow?
I have the plugin project checked out, so I have to make changes to that, uninstall/reinstall (so that the Cordova project picks up the changes), test, repeat. Also, (re)installing is a pain because the plugin name doesn't match the manifest name (or I'm doing something wrong).
Is there a better workflow than this? It's a pain...
Thanks.
AT
Hi @atannus
The development flow I would suggest is to edit the plugin while installed: use a very simple Ionic app that uses this map, run "ionic run android", then open the Android project into the IDE you like (eg. Android Studio) and edit directly in here with live reload allowed by Android Studio.
For clusters, I think you missed the point: the goal is to let the map decide, depending on the zoom level, to show individual markers or to cluster them. If you "create" the clusters outside the plugin, how is it supposed to work? Would you, for every zoom event, recalculate the clusters yourself?
Please tell me if I can help you
Thanks @cvaliere.
On Tue, Mar 15, 2016 at 11:19 AM, cvaliere [email protected] wrote:
Hi @atannus https://github.com/atannus
The development flow I would suggest is to edit the plugin while
installed: use a very simple Ionic app that uses this map, run "ionic run
android", then open the Android project into the SDK you like (eg. Android
Studio) and edit directly in here with live reload allowed by Android
Studio.For clusters, I think you missed the point: the goal is to let the map
decide, depending on the zoom level, to show individual markers or to
cluster them. If you "create" the clusters outside the plugin, how is it
supposed to work? Would you, for every zoom event, recalculate the clusters
yourself?Please tell me if I can help you
—
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub:https://github.com/mapsplugin/cordova-plugin-googlemaps/issues/835#issuecomment-196842172
André Tannús | Epungo | +55 11 2389-4360
We are a layer
Can you share the createMarkers method with us? I think it's would be a great evolution.
Hi @atannus
+1 for sharing createMarkers, I would definitely use it
thanks !
Hi guys.
Thanks for the support.
Aside from createMarkers, changes to the bridge call are also required. In
fact, I created a whole new bridge call for this performance issue. Also,
there's the need to keep track of the created markers, which I've done in
an experimental manner. _I consider the code I wrote a hack up_, and I'm
not comfortable sharing it just yet, especially since I did not bake in
support for the various different ways to provide de marker image.
Last week I put some time into making these changes decent enough to
contribute, but I could not finish the work.
I'll post something soon, please be patient.
On Fri, Mar 18, 2016 at 1:27 PM, cvaliere [email protected] wrote:
Hi @attanus
+1 for sharing createMarkers, I would definitely use it
thanks !
—
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
https://github.com/mapsplugin/cordova-plugin-googlemaps/issues/835#issuecomment-198436813
André Tannús | Epungo | +55 11 2389-4360
We are a layer
Hi guys.
I've pushed the proposed changes to my fork, under branch develop/multiple-markers.
https://github.com/atannus/cordova-plugin-googlemaps/tree/develop/multiple-markers
Support is still very limited, and only tested with URL icons. You must preload icons in order to achieve the performance enhancement. If you don't, icons won't be cached and will be loaded individually, just as if you were adding markers one by one.
Here is some code that demonstrate the plugin in action. Remeber to change the icon paths to something real.
var map;
var icons = [
"http://some.thing/path/to/image1.png"
];
document.addEventListener("deviceready", function () {
// Initialize the map.
var div = document.getElementById("map_canvas");
map = plugin.google.maps.Map.getMap(div);
var initPosition = new plugin.google.maps.LatLng(-23.548, -46.5745);
map.addEventListener(plugin.google.maps.event.MAP_READY, function (map) {
// Post-preload callback.
var donePreloading = function () {
// Animate camera.
map.animateCamera({
'target': initPosition,
'zoom': 16,
'duration': 1000
},
function () {
placeMarkers();
})
};
// Preload images.
map.preloadImages(icons, function (results) {
donePreloading();
});
});
}, false);
placeMarkers = function () {
var markerDefinitions = createMarkers();
map.addMarkers(markerDefinitions, function (createdMarkers) {
console.log(createdMarkers);
});
}
createMarkers = function () {
var markers = [];
for (var i = 1; i < mockData.length; i++) {
var mock = mockData[i];
var position = new plugin.google.maps.LatLng(mock.lat, mock.lng);
var markerDefinition = {
'position': position
, 'icon': {
'url': icons[0],
'size': {
'width': 32,
'height': 32
}
}
};
markers.push(markerDefinition);
}
return markers;
}
var mockData = [
{
lat: "-23.548922600000000",
lng: "-46.574610800000000",
},
{
lat: "-23.549337900000000",
lng: "-46.574795600000000",
},
{
lat: "-23.550828933700000",
lng: "-46.576023101800000",
},
{
lat: "-23.550889500000000",
lng: "-46.576046300000000",
},
{
lat: "-23.551199100000000",
lng: "-46.575804400000000",
},
{
lat: "-23.550761500000000",
lng: "-46.575932700000000",
},
{
lat: "-23.550820100000000",
lng: "-46.575986100000000",
},
{
lat: "-23.550958200000000",
lng: "-46.576498800000000",
},
{
lat: "-23.550552368200000",
lng: "-46.574832916300000",
},
{
lat: "-23.550529480000000",
lng: "-46.575012207000000",
},
{
lat: "-23.549200058000000",
lng: "-46.573200225800000",
},
{
lat: "-23.549949646000000",
lng: "-46.572673797600000",
},
{
lat: "-23.550093900000000",
lng: "-46.572460600000000",
},
{
lat: "-23.550067000000000",
lng: "-46.572427400000000",
},
{
lat: "-23.549314300000000",
lng: "-46.571722400000000",
},
{
lat: "-23.548916800000000",
lng: "-46.572370800000000",
},
{
lat: "-23.550040200000000",
lng: "-46.571646100000000",
},
{
lat: "-23.551219500000000",
lng: "-46.571387300000000",
},
{
lat: "-23.550374984700000",
lng: "-46.571079254200000",
},
{
lat: "-23.551379900000000",
lng: "-46.572379600000000",
},
{
lat: "-23.551279068000000",
lng: "-46.571372985800000",
},
{
lat: "-23.550819700000000",
lng: "-46.571475300000000",
},
{
lat: "-23.550776800000000",
lng: "-46.571910200000000",
},
{
lat: "-23.551599502600000",
lng: "-46.575599670400000",
},
{
lat: "-23.551599502600000",
lng: "-46.575599670400000",
},
{
lat: "-23.552324295000000",
lng: "-46.575397491500000",
},
{
lat: "-23.551766600000000",
lng: "-46.575586100000000",
},
{
lat: "-23.551599502600000",
lng: "-46.575599670400000",
},
{
lat: "-23.552499771100000",
lng: "-46.574798584000000",
},
{
lat: "-23.552565800000000",
lng: "-46.574789700000000",
},
{
lat: "-23.552565800000000",
lng: "-46.574789700000000",
},
{
lat: "-23.551799774200000",
lng: "-46.573898315400000",
},
{
lat: "-23.551788330100000",
lng: "-46.574462890600000",
},
{
lat: "-23.551799774200000",
lng: "-46.573898315400000",
},
{
lat: "-23.553100585900000",
lng: "-46.575500488300000",
},
{
lat: "-23.553400039700000",
lng: "-46.575199127200000",
},
{
lat: "-23.553100500000000",
lng: "-46.574628900000000",
},
{
lat: "-23.552700042700000",
lng: "-46.573799133300000",
},
{
lat: "-23.553236007700000",
lng: "-46.574249267600000",
},
{
lat: "-23.553236007700000",
lng: "-46.574249267600000",
},
{
lat: "-23.552700042700000",
lng: "-46.573799133300000",
},
{
lat: "-23.553236007700000",
lng: "-46.574249267600000",
},
{
lat: "-23.552421900000000",
lng: "-46.573419800000000",
},
{
lat: "-23.552553176900000",
lng: "-46.573181152300000",
},
{
lat: "-23.552079300000000",
lng: "-46.572764700000000",
},
{
lat: "-23.552452087400000",
lng: "-46.573001861600000",
},
{
lat: "-23.552553176900000",
lng: "-46.573181152300000",
},
{
lat: "-23.552080154400000",
lng: "-46.572765350300000",
},
{
lat: "-23.552339553800000",
lng: "-46.571506500200000",
},
{
lat: "-23.552373800000000",
lng: "-46.571509900000000",
},
{
lat: "-23.551967620800000",
lng: "-46.571239471400000",
},
{
lat: "-23.553024292000000",
lng: "-46.572566986100000",
},
{
lat: "-23.553100585900000",
lng: "-46.572799682600000",
},
{
lat: "-23.553188324000000",
lng: "-46.573322296100000",
},
{
lat: "-23.553508758500000",
lng: "-46.573505401600000",
},
{
lat: "-23.552674900000000",
lng: "-46.573789000000000",
},
{
lat: "-23.552713600000000",
lng: "-46.573731100000000",
},
{
lat: "-23.553152200000000",
lng: "-46.571818300000000",
},
{
lat: "-23.553367614700000",
lng: "-46.571437835700000",
},
{
lat: "-23.553100585900000",
lng: "-46.571701049800000",
},
{
lat: "-23.553808212300000",
lng: "-46.571708679200000",
},
{
lat: "-23.553110600000000",
lng: "-46.571771400000000",
},
{
lat: "-23.553100585900000",
lng: "-46.571701049800000",
}
];
Hi everyone, this is Masashi who is the original author of this plugin.
I have already known this issue, many people crime to me since old versions, and I know what I should do.
I left this project at once (because it was crazy busy), but I came back to this project again.
Now, I have been fixing the issues currently filed one bye one.
I will buckle down this issue also. Hold on please.
Thank you @atannus for your work
Hi @wf9a5m75 it's good to have you back :)
Do you have an idea when you can release a new version?
Sorry I have no idea when next is released at this point.
I'm happy to help with anything I can.
Thank you for waiting.
The one of the big problem is that the plugin uses reflection technique both Android and iOS.
Reflection is useful technique for me, because any methods are executable like pointer, but it is slow.
And thank you for testing. This might effect.
https://github.com/cabify/cordova-plugin-googlemaps/blob/d6192536b02093a66f2209580cf8532aca2793e5/src/android/plugin/google/maps/GoogleMaps.java#L792-L825
@wf9a5m75 should we port that changes?
Not test it yet.
Here an example of performance on Android, quite annoying: https://drive.google.com/open?id=0BzzwDw5jEO0xMnhNeklrN2NJaG8
Same amount of markers on iOS works much better, I can try to share a demo video on iOS if you need it as well.
Well, there are just too many markers. This will happen with every implementation without clustering. I don't know how much time it will take to make @wf9a5m75 clustering-plugin to work fine with the current codebase. I don't think that the Codechanges mentioned above will help - but you could try (but as far as I can see, this only take place when resizing)
I have been working on performance optimization.
It's just started a little, but the optimization definitely works with the same code before and after.
test code
Add 200 markers on the map.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript">
// 200 location data
var data = {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[135.5568524,34.580776]}},...,{"type":"Feature","geometry":{"type":"Point","coordinates":[139.616858,35.432656]}}]};
var map;
document.addEventListener("deviceready", function() {
var div = document.getElementById("map_canvas");
var POIs = data.features.map(function(feature) {
return {
position: {lat: feature.geometry.coordinates[1], lng: feature.geometry.coordinates[0]},
icon: "https://iai-dojo.jp/modules/dojo/img/flag9.gif" // <-- In this test code, use the same icon for all.
}
});
// Create bounds
var bounds = POIs.map(function(poi) {
return poi.position;
});
// Initialize the map view
map = plugin.google.maps.Map.getMap(div, {
camera: {
target: bounds
}
});
// Wait until the map is ready status.
map.addEventListener(plugin.google.maps.event.MAP_READY, function() {
var start = Date.now();
addMarkers(POIs, function(markers) {
var end = Date.now();
alert(markers.length + " markers are added : " + ((end - start) / 1000) + " sec.")
});
});
}, false);
function addMarkers(data, callback) {
var markers = [];
function onMarkerAdded(marker) {
markers.push(marker);
if (markers.length === data.length) {
callback(markers);
}
}
data.forEach(function(markerOptions) {
map.addMarker(markerOptions, onMarkerAdded);
});
}
</script>
</head>
<body>
<h3>PhoneGap-GoogleMaps-Plugin</h3>
<div style="width:100%;height:500px" id="map_canvas"></div>
</body>
</html>
Before

After

The optimization is under construction. Please wait for a while for public beta.
It's turn on the iOS. I use the same test code above.
While the current iOS code is not so slow, but the optimized version is more faster.
Before (current master branch)

After

hi @wf9a5m75 your optimization seems very promising!
can't wait to have it :)
Will this improve performance while dragging as well?
@ZiFFeL1992 Which dragging action do you ask, marker or map?
@wf9a5m75 map, sorry for not specifying before :/
@ZiFFeL1992
Current optimization process does not related with the map dragging behavior.
In the feature, I will optimize that.
hi @wf9a5m75
currently using your optimization branch for Android, it works, and it rocks, thanks for your work!
we would like to do the same for iOS, but optimization branch crashes; do you know when you release it? would it help if we give you a snippet that makes it crash?
thanks!
I'm getting 'getMap' is not defined in GoogleMaps plugin. -> BaseClass.js:124.
Optimization branch on Android.
I don't support using the optimization branch. It's under construction.
hi @wf9a5m75
currently using your optimization branch for Android, it works, and it rocks, thanks for your work!
we would like to do the same for iOS, but optimization branch crashes; do you know when you release it? would it help if we give you a snippet that makes it crash?
thanks!
As I said the above, I don't support using the optimization branch. It's under construction.
No ETA.
hi @wf9a5m75
I don't want to be an asshole, but what's the point of so much time?
I mean, I have the impression that the optimization branch is already OK on Android, and very close to be OK on iOS.
If you need help, you could ask for help, but instead you go like "It's OK guys, I'll handle it all by myself"... but it's been 6 weeks now.
Can we do something to help? If so, please ask. If not, could you release this optimization we're all waiting for?
Sorry for late, but keep waiting please.
I have been developing the feature of multiple maps currently.

hi @wf9a5m75
my usual ping for you :)
do you have an ETA now?
hi @wf9a5m75
you sure know how to handle suspense
seriously, what can we do to help?
I've been working on the multiple maps continueously.
I guess the most of methods are worked without problem on iOS(not Android), but I've been testing one by one.
If you are interested in it, try the multiple_maps branch (works only for iOS, Android is not ready yet even for testing)
thanks!
so, if I sum up:
I guess that branch "multiple_maps" may change the API, though? Until now, if we make multiple calls to method getMap, we receive the same instance of map, but I guess it won't be the case anymore?
The getMap() method always return a new instance of a map in the multiple_maps branch.
And the multiple_maps branch iherites the optimization branch, but I've been adjusting the multiple maps action especially on the iOS.
OK, so we have to change our JS code a bit, because until there, when we called getMap(), it was always the same instance, so there was no need to redefine events listeners for instance
The problem is that we need to have a common API for Android & iOS, so I will wait until multiple maps is ready for both platforms
Any ETA?
No ETA, sorry.
I was busy until 3 days ago (since my mother was died...)
My sincere condolences. Take all the time you need
My condolences too
If you want to stop for a while, which would be totally understandable, please just provide what's left to develop on Android, and I'll develop it
I'm sorry to hear about your loss @wf9a5m75
my usual ping
current situation is that
and it's been 5 months now
please tell us if you need help
@wf9a5m75
6 months
same situation
help still available if you decide to value teamwork
@cvaliere
Thank you for waiting long time.
As you may know, I don't stop at all. I have still working on many things little by little.
You can catch up what I do.
https://github.com/mapsplugin/cordova-plugin-googlemaps/commits/multiple_maps
So what's now.
I'm focusing on the multiple maps with multiple pages.
This is an example apk (alpha version level).
(apk)
https://drive.google.com/open?id=0B1ECfqTCcLE8QVBWNl9pd2lyX00
(youtube)
https://www.youtube.com/watch?v=Insz0tPCB44
The reason of what I don't receive your help(s) is that
I have been strengthening the foundation of the plugin.
In order to improve performance, saving memory, and use multiple maps,
The codes of Javascript and the native side are becoming stable, but not stable, still changing.
In order to work with the team, I need to make the load map,
but since the unexpected things are still happen some time,
not yet the time. Please wait.
(However I have been preparing it)
Regarding of the multiple_maps branch, I'm working on the map and the marker classes only.
If I feel the two classes are stable, I will ask to help for other classes such as Polyline, Polygon...etc.
You can test the branch, but no guarantee, no crams please.
thank you for your answer
I indeed see that you make progress, but sadly, I _must_ use this new branch: performance on master is awful, and I do need multiple maps
We are desperately trying to use branch multiple_maps, but we are stuck. We made a fork here: https://github.com/elpsk/cordova-plugin-googlemaps/commits/multiple_maps, and we already fixed some things, but we still have an enormous issue on iOS, with the map being hidden below all other elements
@cvaliere Is that branch working on Android?
dunno yet, we are trying to make it work on iOS
just creating the map and putting a marker on it, and it doesn't work...
I'm desperate
Um, did you install this https://github.com/apache/cordova-plugins/tree/master/wkwebview-engine-localhost ?
nope
should I?
Yes, at this time. In the feature, you will not need to install (probably).
And, the wkwebview-engine-localhost plugin inserts <content src="http://localhost:0" /> under <widget> tag, but this is a problem for Android.
So you need to modify the config.xml like below.
<?xml version='1.0' encoding='utf-8'?>
<widget id="cordova.google.maps" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>HelloCordova</name>
<description>
A sample Apache Cordova application that responds to the deviceready event.
</description>
<author email="[email protected]" href="http://cordova.io">
Apache Cordova Team
</author>
<plugin name="cordova-plugin-whitelist" spec="1" />
<access origin="*" />
<access origin="*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<preference name="AlternateContentSrc" value="http://localhost:0" />
<content src="http://localhost:0" />
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
</widget>
to be sure I understand:
thanks
As long as you want to make XHR request on file:///, you will need engine-localhost - otherwise, a lot of thing won't work. Also make sure, that you've pointed out correct policies inside of meta-data (default-src, img etc.)
By the way: Just want to spit out an important warning here:
• From current iOS 10 Beta, I would recommend to stay FAR away from WKWebView and stick back to UIWebView, as user-scalable=no won't be supported. This is on apples radar, but I am damn sure that they won't listen to there users again. This means, that "PINCH TO ZOOM" will be active automatically and can't be prevented (maybe with some dirty touch-hacks, but I did not test this)
This warning comes also from famous Developer @EddyVerbruggen and some other Cordova-Team members
Edit:
Source: https://github.com/Telerik-Verified-Plugins/WKWebView/issues/249
currently, your master branch doesn't require to have WKWebView, right?
yes
but your new multiple_maps branch requires it, right?
yes, at this time.
is it the reason why we don't see the map on iOS?
probably.
WKWebView seems to add some shitty problems, particularly on iOS8, are you aware of any?
Oh, I see, but in order to test, please add it.
@Hirbod can you give the reference to the issue you're talking about?
edited my post
seems fixed in iOS 10 beta 4? https://www.idevice.ro/2016/08/01/ios-10-beta-4/
we still can't manage to make it work :(
now, with the wkwebview-engine-localhost, the map appears, the markers appear, but all others objects in the page are not responding to touch (menu, tabs, etc...)
do you have a working example on iOS?
As I said, the map and the marker classes only.
And I've been working on the iOS touch issue.
We are testing with only map and marker
But the rest of the page (HTML) are not responding to touch
What do you mean "I've been working on the iOS touch issue"?
Hi @wf9a5m75 ,
here you can find the demo app that reproduce the touch issue on iOS.
Please let me know what i'm doing wrong...
https://github.com/elpsk/cordova-plugin-googlemaps-multiplemaps-ios
thanks
@cvaliere
What do you mean "I've been working on the iOS touch issue"?
I'm fixing this problem But the rest of the page (HTML) are not responding to touch.
@elpsk
Thank you, but I already know it and working to fix it.
@wf9a5m75 can you tell us when this plugin is able to display a map and a marker, please?
there is no point that we lose our time trying to make it work, if it's not even able to correctly display a map...
No ETA. Sorry.
dude, you remember what you wrote in March?
Hi everyone, this is Masashi who is the original author of this plugin.
I have already known this issue, many people crime to me since old versions, and I know what I should do.
I left this project at once (because it was crazy busy), but I came back to this project again.
I will buckle down this issue also. Hold on please.
it's unbelievable
some nice people were trying to make this plugin better, they all have stopped their work because you said you would take care of it, and 6 months after, it's not even able to display a map??
how disrespectful are you?
Hey @cvaliere, just trowing my 2 cents out there..
Instead of having to use the optimized version which is not supported, did you try to handle the marker creation in a different way on javascript? I also have lots of markers in my app and things work just fine by throttling the creation and giving some time to the UI to refresh every few miliseconds..
If you disappoint my work, sorry. But it's open source.
You can folk and modify, create your version anytime.
I said many times in many issue threads, my time is very limited every day.
it's not even able to display a map??
At least on my iOS simulater and iOS device, no problem to display the maps.
But I know the touch issue on iOS, and working to fix it in couple of days.
@quiuquio thank you for the idea, but creating markers with this plugin is slow, period; it is a nightmare on Android, and a smaller nightmare on iOS, but still a nightmare; according to masashi's tests, the new branch is 3 times faster on iOS, and 30 times faster on Android(!!) And also, I need multiple maps
@wf9a5m75 your work is open source, but you killed every will of participating when you came back in march and said that you knew what you had to do and that you would do it. Since then, no one has done anything because we are all waiting for you to release what you promised! And 6 months and 143 commits later, it is still not even able to display a map, it's crazy
At least on my iOS simulater and iOS device, no problem to display the maps
Yes, strictly speaking, it is able to display a map; but in exchange, it destroys the rest of my application. Let me think if I wanna use it... errrrr... no
We're also having significant issues regarding the extreme slowness & memory usage on Android. We'd be happy to sponsor any patches and related features such as clustering, however, it seems that there's no such possibility at this moment.
Masashi: Your plugin is great. It has enabled many of us to build good apps that include maps. It is stable, very versatile and well documented. I also understand you're very busy and have to deal with personal matters as well. Please, consider encouraging and including other developers' efforts so that we can have an even better plugin for the community to use.
I reckon that many of us use this plugin in commercial projects and time is always a factor when building commercial apps.
@wf9a5m75 I see that you commited 'Bug fix : The plugin detects user click position on iOS.'
does it mean that it works now?
thanks
Finally (I believe so), the problem of clicking position is incorrect on iOS is fixed.
And one more thing, next version will allow you to use fixed position (such as header).
This means the plugin watches all HTML element positions periodically instead of the child elements.
This is implemented on iOS currently (Android is not implemented yet).
https://youtu.be/ajysxJ9H6rc
great, gonna test that
doesn't work
dunno why
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* setObjectForKey: object cannot be nil (key: map_0_293554574284)'
*** First throw call stack:
(0x27c8049f 0x35436c8b 0x27b9dc63 0x245687 0x20bcbb 0x16e09db 0x16e09c7 0x16e43ed 0x27c463b1 0x27c44ab1 0x27b923c1 0x27b921d3 0x2ef900a9 0x2b1a1fa1 0x3bb43 0x359b6aaf)
libc++abi.dylib: terminating with uncaught exception of type NSException
Please post all stack logs, not just first row.
nope
I lost enough time with your it's-been-6-months-but-I-still-don't-work plugin
we found another solution
After I posted the last comment, I already committed another bug fixes.
But anyway, you found another solution, that's fine. Please go ahead.
I will go on my way, on my pace.
@cvaliere Would you mind sharing your solution? Thanks!!
@adrinavarro
on Android, we use branch optimization of this plugin, which works well
and on iOS, we continue, sadly, to use branch master, which main flaw is that it freezes UIWebView randomly when removing markers; after transiting to WKWebView with Ionic's brand new plugin (https://github.com/driftyco/cordova-plugin-wkwebview-engine), it doesn't freeze anymore
I'd still love to use multiple_maps, but, hey... no ETA!
Well, it makes me happy to hear that! We'll see if the optimization branch helps us (we have 500+ markers… we were hoping for clustering as well, right now anything is bad). I'm excited for WKWebView as well, we were wondering if it was production ready though.
Wow that WKWebView Plugin just worked perfectly. The XHR interceptor is so simple and still so genius. Never thought about that. I changed it flawlessly inside of my projects, thanks for that solution.
well, Ionic released this plugin last week, and they say it's not production ready yet; we made our own tests, and it seems OK for us, a lot better than the official apache plugin or the one from Telerik
500+ markers is a lot; shouldn't be too big a problem with branch optimization for Android and WKWebView for iOS, but have you considered making clustering server-side?
Clustering is a user-space decision, it should not be a plugin feature.
A cluster is _simply a marker_ that represents multiple places/things. The _user_ should handle clustering and insert a single marker where the cluster is. It's a lot simpler and flexible to think of it this way.
Having the server-side return the positions and sizes of clusters follows this general guideline. The plugin should concentrate on exposing the Android Maps API through Cordova, not reinventing it.
Please see my Feb 3 comment.
IMHO it should be a plugin feature
It's not a matter of opinion, it's an application of the principle of
separation of responsibilities.
On Thu, Aug 25, 2016 at 9:30 AM, Hirbod [email protected] wrote:
IMHO it should be a plugin feature
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/mapsplugin/cordova-plugin-googlemaps/issues/835#issuecomment-242368921,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAo2mxnFCbFWsY-PzCt3KfM0_ehtEGZlks5qjYrwgaJpZM4HQ9q5
.
André Tannús | Epungo | +55 11 2389-4360
We are a layer
Well, this is your opinion. Google and other map frameworks provide SDKs for creating clustering on client side. It's there for reason. Server-Side Clustering can be a heavy database and CPU consuming process and there is need for beeing able to do this clientside. Not always, but for enough people.
Exactly.
Google and other map frameworks provide facilities for clustering, they don't handle it internally, which is precisely what I am proposing. Again, see Feb 3.
I never said server side was better, I said it was in line with not being handled by the Maps Plugin. What I did say is that clustering should done by the user, not by the plugin. Whether it bill be done in the device or server-side is up to the user.
If clustering is too intensive you have yet another reason why it should be done server-side, and cached.
@wf9a5m75 so what do you recommend me? (Of course I was aware of this thread but opened a new one because I can't see a solution out of this one)
This is the demo that current status.
APK
https://drive.google.com/open?id=0B1ECfqTCcLE8QVBWNl9pd2lyX00
So pls let me make a conclusion:
is that right?
--> If yes: pls understand as mentioned before by lots of other people that time is a limiting factor for most of us. Thus I would prefer if you can make a statement if it would take 3 months, 6 months, 1 year, 2 years or 5 years for you. It is not important if this is exactly right but than everyone can decide how to proceed with his/her project and this maps plugin.
--> If no: Maybe the other people here should decide to make a fork to get some more features in it and than it would be okay as well because from my point of view the only thing I currently missing is marker clustering, with this feature it would resolve all my open problems with the map I think.
P.S.: I really can not understand why everyone else has stopped working and lots of people (myself as well) have offered their support without feedback, which is killing the open source mind in my opinion. If sb. can link me to a previous discussion about the future of this plugin that I can comprehend this would be great, thx.
@Mojo90
In current stable version (1.3.9) it is not possible to get satisfying results with a bunch of markers (maybe 500 or 1000+)
Yes.
marker clustering is needed to get a great result and UX (no lagging anymore, no overlaying markers etc.)
Yes, but I haven't develop it now (I developed this at once, but not ready yet).
you (@wf9a5m75) are currently developing version 1.4 of this plugin which will resolve all this issues
Yes, except the marker cluster.
And adding the feature of multiple maps, and etc.
Even though you saystime is a limiting factor for most of us, my private time is also very limited.
This is NOT company's product, this is just hobby code.
I applicate for offering to help, but during the developing, the code (and internal mechanism) will change severely. That's why I don't accept any help right now.
I can not promise the ETA, since even for me, the unknown new issues are happen in order to implement the safe feature for Android and iOS.
I don't mind that you folk and create your original version, if you don't satisfy the current status.
@wf9a5m75 thx for your answer.
I assumed that this is your hobby code as it would be for others contributors. But I think you must understand that some people rely on plugins for commercial products and so its better to share the load of developing new features and optimize old code with others. but imho what you are doing right now since beginning of this year kills all the good reputation this plugin earned in the past. But its your decision, you are the initial author so let me say "its your baby".
As this thread has Milestone of 1.4.0 I assume marker clustering will be included in the next release you will publish (whenever it will be).
@Mojo90
I don't mind if you or other people use this plugin for commercial app, but it's not related to me.
If you force me hurry up, it's easy.
You just pay $1,500,000 for the company I belong to.
It makes me a time to focus on to this plugin during the work time for a few weeks.
But you probably don't want pay it, there is no time to improve my time.
Otherwise, you should create your version.
I'm really stressful for pushing your schedule, that's why I open this plugin as open soirce and loose license.
I won't include marker cluster for next version at least.
I see, no problem. I think its best way to do my own version even if you will not include clustering in the next version, because this is the feature I am waiting for almost a year now. I already thought about this a year ago because it needs ~100 LoC per platform from SDK point of view, isn't it? But than @Hirbod implemented it with other developers and it was never released - also another strange story.
But nevertheless @wf9a5m75 a great plugin, thx!
But than please remove Milestone 1.4.0 from this thread that this will not mislead other people, because this issue won't be fixed with next version.
this plugin is not "a great plugin", it's a shitty plugin with shitty performance, tons of bugs and a ridiculous limitation to a single map, and that's exactly why @wf9a5m75 is rebuilding it entirely; for the joke, branch "multiple_maps" is 179 commits ahead of master, and if you make the diff, you'll see that not a single file has been spared from this total rewrite
@wf9a5m75, would $1000 encourage you to hurry up?
@cvaliere Thank you for your patient. I'm working on everyday recently.
I can not promise you but it's not so long far to finish up.
Temporally ETA is end of this month (PDT).
Thank you for offering the amount, but I can not receive it since even receive it, my free time is not increased. I only receive your kindness.
@cvaliere I already thought of use cases for multiple maps, can you please tell me some? nothing very important came in my mind...
@Mojo90: What do you mean? Multiple maps simply means that you can initialize multiple maps. In our case, this means we can have a tab with a map ("always on") then initialize and destroy maps as needed for detail cards, settings, etc.
same here: we have a permanent tab with a map, and we also want to have occasional maps for detail cards
@cvaliere you should really leave this forum. I'm sick of your attitude. When this is a shitty plugin and has ton of problems for you (because it just don't fit your needs), go ahead and develop your very own version. I don't know who you think you are. When you want to build something commercial then go ahead, hire an iOS and Android developer, pay like 5000-8000 € per month and create your own, perfect, non-shitty plugin and be disrespectful with them. After that, create a Git, and share your perfect solution with everybody.
If not, shut the hell up. I really don't know how you even dare making demands on an open source project.
but you can remove markers and readd with new and restyle map if needed. or what is the problem here? From performance point of view isn't it better to just add one and fit that map according to your needs?
@Mojo90 while your solution is legit, it's not so snappy. You will always have a little small delay and flickering. Multiple map instances will give you the ability to keep your "main" map, and create another one. (maybe a smaller version, which has focus on a special location or something)
@Hirbod I was expecting someone to react like you :)
Let me just remember that I offered my own help as a developer 6 times in this thread, always refused; I spent dozens of hours to test this multiple_maps, never worked; and I even made my own fork to try to make it work, but it was so buggy that it was pointless
What makes me sick is that this "open source" project is not open source anymore, since @wf9a5m75 decided, 7 months ago, to refuse any contribution, saying that he would handle everything by himself; and since then, we're all desperately waiting for something to happen
Sorry if "shitty" offends you, but when you see that master branch is 40 times (!) slower than optimization branch, the only conclusion you can make as a developer is that it's really bad; and apparently, @wf9a5m75 came to the same conclusion, as he is rewriting everything
If you disliked my "attitude", at least admit that I do what I can to make this "open source" project evolve; I don't "make demands", I'm offering my contribution, which is refused; and now I'm offering money
@cvaliere Just let him finish the multiple map branch, and after that, we all will appreciate any help we can get.
The current problem is (maybe due to @wf9a5m75 workflow), he works on multiple branches, locally + remotely (and also changing codebase quickly) etc, and any help would make him lose his track as he has to cross-merge etc. (at least I am thinking it is like that).
After multiple maps is finished (which hopefully has the optimization incorporated), we have a "new master" which we can work on together - and a better organized github structure.
and I will be happy to contribute to this new master
happy to know it could happen by the end of the month
@Hirbod Thank you for helping me.
he works on multiple branches, locally + remotely (and also changing codebase quickly) etc, and any help would make him lose his track as he has to cross-merge etc. (at least I am thinking it is like that).
Exactly. The code changes quickly to fix issues (if I do like this with other people, they have so much stress).
That's why I can not accept helping offers.
@cvaliere
I know you have so much stress the current status. If I were you (like use this plugin in commercial), I probably have much stress, or start to develop own version.
I will finish the multiple_maps branch working by the end of this month.
At least like beta. (Beta means that the no code changes dramatically.)
Merge to the master, or not, I will discuss with @Hirbod at the time.
@cvaliere @Mojo90 +1 for clustering, that is a much awaited feature of this plugin!
Hi, +1 for clustering any updates ??
Hi everyone.
As I said before, today is the day. The next version (2.0-beta) is ready to go (however beta).
First of all, try the demo app. You can download from my dropbox.
cordova-googlemaps-v2-demo_01.apk
https://www.youtube.com/watch?v=oZBkTIpjTqg

There are several changes.
As you may know, the next version supports multiple map in the same html.
However one map takes large memory, so I recommend 2,3 maps at the one page.
If you don't use a map, remove it. That's save the memory.
Version 1.x supports only single html file (typically index.html)
The next version supports multiple HTML file (such as index.html, page1.html, page2.html ...etc)
You don't need to cleanup the maps if you change html files.
The plugin will do automatically.
However, changing tab page in the same html is a different.
You need to still do map.setVisible(true/false) by yourself.
Version 1.x supports only under the map div.
The next version recognize all HTML element of the page.
It means you don't need to execute map.setClickable(true/false) when HTML dialog is popped up on the map div.
Here is the tips
If the plugin does not recognize your HTML elements on the map div, specify css
.dialog {
position: fixed;
z-index: 1000; //any value is fine
}
Since the html elements that have position:fixed takes a priority always in the maps plugin.
(You don't need to do this usually (I believe so))
The problem of the version 1.x is the KeepWatching Timer.
This timer watches HTML element positions under the map div periodically.
However, if you don't do anything on your app, still the timer is running.
This is affect for battery life.
In the next version, the timer stops automatically if the user does not touch on the map anything for a while.
If the user touch on the app again, the timer also starts.
If no changes for a while, stop the timer again.

If you need to start the timer programmatically, you can do like this:
cordova.fireDocumentEvent('touch_start', {});
or
var event = document.createEvent('touch_start');
event.initEvent(eventName, false, false);
document.dispatchEvent(event);
Another big problem of the version 1.x is that all (most) native code run on the UI thread (or run on the WebCore thread.
The reason of this is the Google Maps native APIs require do it.
However I tested so much time and rewrite all most whole code in both native and javascript, the most code run on the background thread.
And you are lucky. I work as Android developer usually. I work for one
If you don't understand this talk , you can skip this. Just remember the performance is improved.
The version 1.x code of the Javascript is googlemaps-cdv-plugin.js
The file includes 2873 lines. Wow, it's too large. Not suite for maintenance...even for me.
I split the JS files for each classes (such as Marker.js, Circle.js, etc)
https://github.com/mapsplugin/cordova-plugin-googlemaps/tree/multiple_maps/www
You can debug easily :)
If you are familiar with the Google Maps Javascritp API v3, you probably know the MVCArray class
The benefit of this class is you can monitor the events: insert_at, set_at, and remove_at.
Using this class, your code would be simple.
This is really useful. Most of getXXXX() methods return the values as normal javascript object.
For example, in version 1.x,
marker.getPosition(function(position) {
// you have to wait the callback
});
in version 2.0-beta
var position = marker.getPosition();
You know what? Since the marker (and polyline,polygon...etc) extends the BaseClass (which is MVC class), you can monitor like this.
markers[0].on("position_changed", onPositionChanged);
markers[1].on("position_changed", onPositionChanged);
markers[2].on("position_changed", onPositionChanged);
function onPositionChanged() {
var marker = this;
var position = marker.getPosition();
}
However, map.getVisibleRegion() does not support this way.
you still have to use callbak.
In version 2.0, most of all setXXX() methods are able to chain.
marker.setPosition({"lat": ...., "lng": ....}).setTitle("Hello");
| event name | Androide | iOS |
|---|---|---|
| event name | Android | iOS |
| - | - | -|- |
| MAP_CLICK | YES | YES |
| MAP_LONG_CLICK | YES | YES |
| MY_LOCATION_CHANGE | YES | NO |
| MY_LOCATION_BUTTON_CLICK | YES | YES |
| INDOOR_BUILDING_FOCUSED | YES | YES |
| INDOOR_LEVEL_ACTIVATED | YES | YES |
| CAMERA_CHANGE | YES | YES |
| CAMERA_IDLE | NO | YES |
| MAP_READY | YES | YES |
| MAP_LOADED | YES | NO |
| MAP_WILL_MOVE | NO | YES |
| MAP_CLOSE | YES | YES |
| OVERLAY_CLICK | YES | YES |
| INFO_CLICK | YES | YES |
| MARKER_DRAG | YES | YES |
| MARKER_DRAG_START | YES | YES |
| MARKER_DRAG_END | YES | YES |
| event name | Androide | iOS | arguments[0] |
|---|---|---|---|
| MAP_READY | YES | YES | none |
| MAP_CLICK | YES | YES | LatLng |
| MAP_LONG_CLICK | YES | YES | LatLng |
| MY_LOCATION_BUTTON_CLICK | YES | YES | none |
| INDOOR_BUILDING_FOCUSED | YES | YES | none |
| INDOOR_LEVEL_ACTIVATED | YES | YES | building information |
| CAMERA_MOVE_START | YES | YES | true if the camera move start by gesture |
| CAMERA_MOVE | YES | YES | CameraPosition |
| CAMERA_MOVE_END | YES | YES | CameraPosition |
| POLYGON_CLICK | YES | YES | LatLng(clicked position) |
| POLYLINE_CLICK | YES | YES | LatLng(clicked position) |
| CIRCLE_CLICK | YES | YES | LatLng(clicked position) |
| GROUND_OVERLAY_CLICK | YES | YES | LatLng(clicked position) |
| INFO_CLICK | YES | YES | LatLng(marker position) |
| INFO_LONG_CLICK | YES | YES | LatLng(marker position) |
| INFO_CLOSE | YES | YES | LatLng(marker position) |
| INFO_OPEN | YES | YES | LatLng(marker position) |
| MARKER_CLICK | YES | YES | LatLng(marker position) |
| MARKER_DRAG | YES | YES | LatLng(marker position) |
| MARKER_DRAG_START | YES | YES | LatLng(marker position) |
| MARKER_DRAG_END | YES | YES | LatLng(marker position) |
use plugin.google.maps.environment.setBackgroundColor()
You can do like this
plugin.google.maps.Geocoder.geocode({
"address" : [
"address1", "address2" ... "addressN"
]
}, function( mvcArray ) {
mvcArray.on('insert_at', function(index) {
console.log( mvcArray.getAt(index) );
});
});
I forgot to much. See the demo apk.
map.showDialog(), map.closeDialog(), and map.addKmlOverlay() are not ready yet.
Both are Supported.
Crosswalk is not confirmed yet.
I think I miss something. I will post them if I remember.
Oh, I just remember, the tileoverlay, ground overlay support the local image files.
And no longer to start with www/
You can use the relative path for path specify (marker, tile overlay, and ground overlay)
Hi everyone,
I prepared the demo apk repository:
https://github.com/mapsplugin/v2.0-demo/
If you face any issues about v2.0-beta, please post to the issue tracker of the demo app, instead of this repository.
I would like to separate the issues.
Okay. Probably you guys are interested in the final result, the v2 is faster than v1?
The test code is here.
var map;
var mockData = [
{
lat: "-23.548922600000000",
lng: "-46.574610800000000",
},
{
lat: "-23.549337900000000",
lng: "-46.574795600000000",
},
{
lat: "-23.550828933700000",
lng: "-46.576023101800000",
},
{
lat: "-23.550889500000000",
lng: "-46.576046300000000",
},
{
lat: "-23.551199100000000",
lng: "-46.575804400000000",
},
{
lat: "-23.550761500000000",
lng: "-46.575932700000000",
},
{
lat: "-23.550820100000000",
lng: "-46.575986100000000",
},
{
lat: "-23.550958200000000",
lng: "-46.576498800000000",
},
{
lat: "-23.550552368200000",
lng: "-46.574832916300000",
},
{
lat: "-23.550529480000000",
lng: "-46.575012207000000",
},
{
lat: "-23.549200058000000",
lng: "-46.573200225800000",
},
{
lat: "-23.549949646000000",
lng: "-46.572673797600000",
},
{
lat: "-23.550093900000000",
lng: "-46.572460600000000",
},
{
lat: "-23.550067000000000",
lng: "-46.572427400000000",
},
{
lat: "-23.549314300000000",
lng: "-46.571722400000000",
},
{
lat: "-23.548916800000000",
lng: "-46.572370800000000",
},
{
lat: "-23.550040200000000",
lng: "-46.571646100000000",
},
{
lat: "-23.551219500000000",
lng: "-46.571387300000000",
},
{
lat: "-23.550374984700000",
lng: "-46.571079254200000",
},
{
lat: "-23.551379900000000",
lng: "-46.572379600000000",
},
{
lat: "-23.551279068000000",
lng: "-46.571372985800000",
},
{
lat: "-23.550819700000000",
lng: "-46.571475300000000",
},
{
lat: "-23.550776800000000",
lng: "-46.571910200000000",
},
{
lat: "-23.551599502600000",
lng: "-46.575599670400000",
},
{
lat: "-23.551599502600000",
lng: "-46.575599670400000",
},
{
lat: "-23.552324295000000",
lng: "-46.575397491500000",
},
{
lat: "-23.551766600000000",
lng: "-46.575586100000000",
},
{
lat: "-23.551599502600000",
lng: "-46.575599670400000",
},
{
lat: "-23.552499771100000",
lng: "-46.574798584000000",
},
{
lat: "-23.552565800000000",
lng: "-46.574789700000000",
},
{
lat: "-23.552565800000000",
lng: "-46.574789700000000",
},
{
lat: "-23.551799774200000",
lng: "-46.573898315400000",
},
{
lat: "-23.551788330100000",
lng: "-46.574462890600000",
},
{
lat: "-23.551799774200000",
lng: "-46.573898315400000",
},
{
lat: "-23.553100585900000",
lng: "-46.575500488300000",
},
{
lat: "-23.553400039700000",
lng: "-46.575199127200000",
},
{
lat: "-23.553100500000000",
lng: "-46.574628900000000",
},
{
lat: "-23.552700042700000",
lng: "-46.573799133300000",
},
{
lat: "-23.553236007700000",
lng: "-46.574249267600000",
},
{
lat: "-23.553236007700000",
lng: "-46.574249267600000",
},
{
lat: "-23.552700042700000",
lng: "-46.573799133300000",
},
{
lat: "-23.553236007700000",
lng: "-46.574249267600000",
},
{
lat: "-23.552421900000000",
lng: "-46.573419800000000",
},
{
lat: "-23.552553176900000",
lng: "-46.573181152300000",
},
{
lat: "-23.552079300000000",
lng: "-46.572764700000000",
},
{
lat: "-23.552452087400000",
lng: "-46.573001861600000",
},
{
lat: "-23.552553176900000",
lng: "-46.573181152300000",
},
{
lat: "-23.552080154400000",
lng: "-46.572765350300000",
},
{
lat: "-23.552339553800000",
lng: "-46.571506500200000",
},
{
lat: "-23.552373800000000",
lng: "-46.571509900000000",
},
{
lat: "-23.551967620800000",
lng: "-46.571239471400000",
},
{
lat: "-23.553024292000000",
lng: "-46.572566986100000",
},
{
lat: "-23.553100585900000",
lng: "-46.572799682600000",
},
{
lat: "-23.553188324000000",
lng: "-46.573322296100000",
},
{
lat: "-23.553508758500000",
lng: "-46.573505401600000",
},
{
lat: "-23.552674900000000",
lng: "-46.573789000000000",
},
{
lat: "-23.552713600000000",
lng: "-46.573731100000000",
},
{
lat: "-23.553152200000000",
lng: "-46.571818300000000",
},
{
lat: "-23.553367614700000",
lng: "-46.571437835700000",
},
{
lat: "-23.553100585900000",
lng: "-46.571701049800000",
},
{
lat: "-23.553808212300000",
lng: "-46.571708679200000",
},
{
lat: "-23.553110600000000",
lng: "-46.571771400000000",
},
{
lat: "-23.553100585900000",
lng: "-46.571701049800000",
}
];
document.addEventListener("deviceready", function() {
var div = document.getElementById("map_canvas");
// Initialize the map view
map = plugin.google.maps.Map.getMap(div);
// Wait until the map is ready status.
map.addEventListener(plugin.google.maps.event.MAP_READY, function() {
map.moveCamera({
target : mockData
});
var start = Date.now();
addMarkers(map, mockData, function(markers) {
var end = Date.now();
alert("duration: " + ((end - start) / 1000).toFixed(1) + " seconds");
});
});
function addMarkers(map, data, callback) {
var markers = [];
function onMarkerAdded(marker) {
markers.push(marker);
if (markers.length === data.length) {
callback(markers);
}
}
data.forEach(function(position) {
map.addMarker({
position: position,
icon: {
url: "http://googlemaps.googlermania.com/img/google-marker-big.png",
'size': {
'width': 30,
'height': 52
}
}
}, onMarkerAdded);
});
}
});
Here are results:
| npm version1.3.9 47.1 sec | ![]() |
| v1.3.9 Master branch / commit caf6ec1099 1.0 sec |
|
| v2-beta / commit 906fc04 0.5 sec |
|
Since the v2-beta is too much faster, I will adjust the code. So in the future, may be a little delay.
Another test: loading multiple icon from multiple url
Test code:
var map;
var mockData = [
{
"lat": -3.818353,
"lng": -36.046829,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/775893.jpg"
},
{
"lat": -4.337121,
"lng": -55.832172,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/82426049.jpg"
},
{
"lat": -3.720867,
"lng": -38.504189,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/40139960.jpg"
},
{
"lat": 5.48118,
"lng": -61.89723000000001,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/56409210.jpg"
},
{
"lat": -2.397067,
"lng": -55.18381099999999,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/39748728.jpg"
},
{
"lat": -3.130216,
"lng": -60.02157700000001,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/45744787.jpg"
},
{
"lat": -7.044324,
"lng": -47.44229100000001,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/39343320.jpg"
},
{
"lat": -1.476382,
"lng": -48.470639000000006,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/47494007.jpg"
},
{
"lat": -5.926927,
"lng": -39.186693,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/55809012.jpg"
},
{
"lat": -2.641122,
"lng": -37.260474999999985,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/50409166.jpg"
},
{
"lat": -5.860231,
"lng": -35.181656000000004,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/56514551.jpg"
},
{
"lat": -4.36157,
"lng": -39.562040999999994,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/65213560.jpg"
},
{
"lat": 6.143286,
"lng": -62.760773,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/56409217.jpg"
},
{
"lat": -3.237241,
"lng": -42.93984900000001,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/69143088.jpg",
"place_id": "629510d322296d0f556a3d8b07bd4a2db52805b8"
},
{
"lat": -2.645377,
"lng": -42.93984900000001,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/40239633.jpg"
},
{
"lat": -5.389851388888889,
"lng": -35.25532138888889,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/68898645.jpg"
},
{
"lat": -2.165109,
"lng": -55.11551299999999,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/44259055.jpg"
},
{
"lat": 4.5646,
"lng": -61.21442,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/65321816.jpg"
},
{
"lat": -3.046583,
"lng": -37.382355,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/382413.jpg"
},
{
"lat": -7.703252,
"lng": -38.15465900000001,
"photo_file_url": "http://mw2.google.com/mw-panoramio/photos/medium/62426261.jpg"
}
];
document.addEventListener("deviceready", function() {
var div = document.getElementById("map_canvas");
// Initialize the map view
map = plugin.google.maps.Map.getMap(div);
// Wait until the map is ready status.
map.addEventListener(plugin.google.maps.event.MAP_READY, function() {
map.moveCamera({
target : mockData
});
var start = Date.now();
addMarkers(map, mockData, function(markers) {
var end = Date.now();
alert("duration: " + ((end - start) / 1000).toFixed(1) + " seconds");
});
});
function addMarkers(map, data, callback) {
var markers = [];
function onMarkerAdded(marker) {
markers.push(marker);
if (markers.length === data.length) {
callback(markers);
}
}
data.forEach(function(photo) {
map.addMarker({
position: {"lat": photo.lat, "lng": photo.lng},
icon: {
url: photo.photo_file_url,
'size': {
'width': 32,
'height': 32
}
}
}, onMarkerAdded);
});
}
});
Here are results:
| npm version1.3.9 1.0 sec | ![]() |
| v1.3.9 Master branch / commit caf6ec1099 1.0 sec |
|
| v2-beta / commit 906fc04 0.7 sec |
|
In the second test, all versions are faster since the Panoramio server is faster.
However, v1.x and v2.x are different mechanism.

The npm v1.3.9 depends on the server response and the network speed.
The v1.3.9 master branch depends on the cache hit percentage.
The v2-beta access to the server in parallel and use cache data.
So this is enough, isn't it?
Yes, nice! (With murker clustering i think it would be perfect ;)
Regarding of the marker cluster feature, I will implement in the future, but not now.
I would like to be in stable the v2-beta before that.
Hope soon
Just send you 100$ - so you can have 50 beer :)
Thank you @Hirbod
Great work @wf9a5m75
huge +1 for clustering support
I also just sent you USD100 - so you can have 50 more beer :)

@samazary Thank you
thank you @wf9a5m75, seems like a great upgrade
I can't use it yet because it crashes immediately with Xwalk. Are you working on it, or can you give me a tip of what should be done, and I'll try to do it?
No xwalk tested. And some method and event names are changed. I recommened you use the plugin in a new project. Don't use it in your project immediately
ok, so, are you working on it, or you want someone else to work on it, and then can you give me a tip of what should be done? (I suppose you know what should be done, as the current master branch supports Xwalk)
Basically I'm not interested in XWalk, but I tried a little.
I don't know why but mapView.onCreate(null); does not work with XWalk.
The below error is inside the MapView (I guess).
In that case, XWalk is not available.
Rejecting re-init on previously-failed class java.lang.Class<lz>: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/android/chimera/Fragment;
at java.lang.Class dalvik.system.DexFile.defineClassNative(java.lang.String, java.lang.ClassLoader, java.lang.Object, dalvik.system.DexFile) (DexFile.java:-2)
at java.lang.Class dalvik.system.DexFile.defineClass(java.lang.String, java.lang.ClassLoader, java.lang.Object, dalvik.system.DexFile, java.util.List) (DexFile.java:299)
at java.lang.Class dalvik.system.DexFile.loadClassBinaryName(java.lang.String, java.lang.ClassLoader, java.util.List) (DexFile.java:292)
at java.lang.Class dalvik.system.DexPathList.findClass(java.lang.String, java.util.List) (DexPathList.java:418)
at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:54)
at java.lang.Class com.google.android.chimera.container.internal.DelegateLastPathClassLoader.loadClass(java.lang.String, boolean) (:com.google.android.gms:28)
at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:312)
at maps.ad.as maps.ad.aw.a(android.content.Context, maps.y.J, maps.ad.ax, java.lang.String, boolean) ((null):0)
at maps.ad.t maps.ad.t.a(com.google.android.gms.maps.GoogleMapOptions, boolean, maps.ad.c) ((null):0)
at void maps.ad.R.a(android.os.Bundle) ((null):-1)
at boolean wg.onTransact(int, android.os.Parcel, android.os.Parcel, int) (:com.google.android.gms.DynamiteModulesB:66)
at boolean android.os.Binder.transact(int, android.os.Parcel, android.os.Parcel, int) (Binder.java:499)
at void com.google.android.gms.maps.internal.IMapViewDelegate$zza$zza.onCreate(android.os.Bundle) ((null):-1)
at void com.google.android.gms.maps.MapView$zza.onCreate(android.os.Bundle) ((null):-1)
at void com.google.android.gms.dynamic.zza$3.zzb(com.google.android.gms.dynamic.LifecycleDelegate) ((null):-1)
at void com.google.android.gms.dynamic.zza$1.zza(com.google.android.gms.dynamic.LifecycleDelegate) ((null):-1)
at void com.google.android.gms.maps.MapView$zzb.zzbru() ((null):-1)
at void com.google.android.gms.maps.MapView$zzb.zza(com.google.android.gms.dynamic.zzf) ((null):-1)
at void com.google.android.gms.dynamic.zza.zza(android.os.Bundle, com.google.android.gms.dynamic.zza$zza) ((null):-1)
at void com.google.android.gms.dynamic.zza.onCreate(android.os.Bundle) ((null):-1)
at void com.google.android.gms.maps.MapView.onCreate(android.os.Bundle) ((null):-1)
at void plugin.google.maps.PluginMap$1.run() (PluginMap.java:223)
Just giving my 2 cents on it: you might not be interested, but Cordova without Xwalk is a big piece of unusable shit. Xwalk=the same web view for every android device. The only real way to provide a good working app. So please don't ignore Xwalk
Move your hands, please.
Although I'm not interested in XWalk, but I'm not leave it completely.
However I have no solution at this time.
So please move your hands to solve the issue.
Thanks.
i have implement this code to render markers with the beta 2 map , according the result of this is on 1.0 secunds with the map beta 2 but on my project are 4.2 secunds ago, i dont idea, i have clone the beta 2 project and set cordova prepare but the time is the same
var map;
var mockData = [
{
lat: "-23.548922600000000",
lng: "-46.574610800000000",
},
{
lat: "-23.549337900000000",
lng: "-46.574795600000000",
},
{
lat: "-23.550828933700000",
lng: "-46.576023101800000",
},
{
lat: "-23.550889500000000",
lng: "-46.576046300000000",
},
{
lat: "-23.551199100000000",
lng: "-46.575804400000000",
},
{
lat: "-23.550761500000000",
lng: "-46.575932700000000",
},
{
lat: "-23.550820100000000",
lng: "-46.575986100000000",
},
{
lat: "-23.550958200000000",
lng: "-46.576498800000000",
},
{
lat: "-23.550552368200000",
lng: "-46.574832916300000",
},
{
lat: "-23.550529480000000",
lng: "-46.575012207000000",
},
{
lat: "-23.549200058000000",
lng: "-46.573200225800000",
},
{
lat: "-23.549949646000000",
lng: "-46.572673797600000",
},
{
lat: "-23.550093900000000",
lng: "-46.572460600000000",
},
{
lat: "-23.550067000000000",
lng: "-46.572427400000000",
},
{
lat: "-23.549314300000000",
lng: "-46.571722400000000",
},
{
lat: "-23.548916800000000",
lng: "-46.572370800000000",
},
{
lat: "-23.550040200000000",
lng: "-46.571646100000000",
},
{
lat: "-23.551219500000000",
lng: "-46.571387300000000",
},
{
lat: "-23.550374984700000",
lng: "-46.571079254200000",
},
{
lat: "-23.551379900000000",
lng: "-46.572379600000000",
},
{
lat: "-23.551279068000000",
lng: "-46.571372985800000",
},
{
lat: "-23.550819700000000",
lng: "-46.571475300000000",
},
{
lat: "-23.550776800000000",
lng: "-46.571910200000000",
},
{
lat: "-23.551599502600000",
lng: "-46.575599670400000",
},
{
lat: "-23.551599502600000",
lng: "-46.575599670400000",
},
{
lat: "-23.552324295000000",
lng: "-46.575397491500000",
},
{
lat: "-23.551766600000000",
lng: "-46.575586100000000",
},
{
lat: "-23.551599502600000",
lng: "-46.575599670400000",
},
{
lat: "-23.552499771100000",
lng: "-46.574798584000000",
},
{
lat: "-23.552565800000000",
lng: "-46.574789700000000",
},
{
lat: "-23.552565800000000",
lng: "-46.574789700000000",
},
{
lat: "-23.551799774200000",
lng: "-46.573898315400000",
},
{
lat: "-23.551788330100000",
lng: "-46.574462890600000",
},
{
lat: "-23.551799774200000",
lng: "-46.573898315400000",
},
{
lat: "-23.553100585900000",
lng: "-46.575500488300000",
},
{
lat: "-23.553400039700000",
lng: "-46.575199127200000",
},
{
lat: "-23.553100500000000",
lng: "-46.574628900000000",
},
{
lat: "-23.552700042700000",
lng: "-46.573799133300000",
},
{
lat: "-23.553236007700000",
lng: "-46.574249267600000",
},
{
lat: "-23.553236007700000",
lng: "-46.574249267600000",
},
{
lat: "-23.552700042700000",
lng: "-46.573799133300000",
},
{
lat: "-23.553236007700000",
lng: "-46.574249267600000",
},
{
lat: "-23.552421900000000",
lng: "-46.573419800000000",
},
{
lat: "-23.552553176900000",
lng: "-46.573181152300000",
},
{
lat: "-23.552079300000000",
lng: "-46.572764700000000",
},
{
lat: "-23.552452087400000",
lng: "-46.573001861600000",
},
{
lat: "-23.552553176900000",
lng: "-46.573181152300000",
},
{
lat: "-23.552080154400000",
lng: "-46.572765350300000",
},
{
lat: "-23.552339553800000",
lng: "-46.571506500200000",
},
{
lat: "-23.552373800000000",
lng: "-46.571509900000000",
},
{
lat: "-23.551967620800000",
lng: "-46.571239471400000",
},
{
lat: "-23.553024292000000",
lng: "-46.572566986100000",
},
{
lat: "-23.553100585900000",
lng: "-46.572799682600000",
},
{
lat: "-23.553188324000000",
lng: "-46.573322296100000",
},
{
lat: "-23.553508758500000",
lng: "-46.573505401600000",
},
{
lat: "-23.552674900000000",
lng: "-46.573789000000000",
},
{
lat: "-23.552713600000000",
lng: "-46.573731100000000",
},
{
lat: "-23.553152200000000",
lng: "-46.571818300000000",
},
{
lat: "-23.553367614700000",
lng: "-46.571437835700000",
},
{
lat: "-23.553100585900000",
lng: "-46.571701049800000",
},
{
lat: "-23.553808212300000",
lng: "-46.571708679200000",
},
{
lat: "-23.553110600000000",
lng: "-46.571771400000000",
},
{
lat: "-23.553100585900000",
lng: "-46.571701049800000",
}
];
document.addEventListener("deviceready", function() {
var div = document.getElementById("map_canvas");
// Initialize the map view
map = plugin.google.maps.Map.getMap(div);
// Wait until the map is ready status.
map.addEventListener(plugin.google.maps.event.MAP_READY, function() {
map.moveCamera({
target : mockData
});
var start = Date.now();
addMarkers(map, mockData, function(markers) {
var end = Date.now();
alert("duration: " + ((end - start) / 1000).toFixed(1) + " seconds");
});
});
function addMarkers(map, data, callback) {
var markers = [];
function onMarkerAdded(marker) {
markers.push(marker);
if (markers.length === data.length) {
callback(markers);
}
}
data.forEach(function(position) {
map.addMarker({
position: position,
icon: {
url: "http://googlemaps.googlermania.com/img/google-marker-big.png",
'size': {
'width': 30,
'height': 52
}
}
}, onMarkerAdded);
});
}
});
I have no idea.
As response to @dsemerida :
Point 5 -> https://github.com/mapsplugin/v2.0-demo/issues/6#issuecomment-253334483
Also noticed this, but I didn't have so much time to deeply investigate it, I'd like to create a sample project with +300 markers and measure the time between 1.4 and 2.0
Hey!
First, thanks for your job, this plugin is awesome :-)
I used the v1 (with Ionic 1) on my app and I'm currently writing a new version using Ionic 2 and the v2 of the plugin. Everything is fine except the markers creation. I add 222 markers on my map.
The v1 handle it without problem, but the v2 is extremely slow on Android :-(
~1.5s on this project (v1) : https://github.com/alexetmanon/vliller
~10s on this project (v2) : https://github.com/alexetmanon/vliller2
I make a test repo here : https://github.com/blckshrk/addmarker-debug
On my Nexus 5 it takes ~1.5s to add 100 markers and ~5s with 200 markers.
I have no idea from where it can come from... Should it be the Android SDK ? Is 200 markers a lot (it seems not on the v1) ? I've tried every thing, but really, I don't get it.
Could you take a look ? :-)
@blckshrk Specify the same icon as much as possible.
The v2 creates image cache internally when the icon properties (url and size) are the same.
I also asked you about this when you released v2 @wf9a5m75 , there's something causing slow drawing of markers on the map in v2.
Point 5: https://github.com/mapsplugin/v2.0-demo/issues/6#issuecomment-253334483
But your answer about that point didn't help so much... https://github.com/mapsplugin/v2.0-demo/issues/6#issuecomment-253339084
I'd love to use v2 since I believe that it will work much better than v1, but adding lots of markers it's a common task, that HUGE time impact will be bad for UX...
Hey guys!
@wf9a5m75 I used the default icon for my tests (so no icons properties) and on the initial app each marker have the same icon object (with same url/size properties)
@ZiFFeL1992 I agree, adding more than 100 marker have a really huge impact on performances, but it seems limited to the Android version (to be confirmed)
Hi,
I've taken a day to dig the problem and I found some issues.
Observations
Marker.create) is fast (around 1ms by marker)callbackContext.success(result); and the execution of the JS callback is really long (around 1,5s).

Interpretation
I suspect a memory leak in the ResizeTask (and maybe somewhere else), which lefts no memory for the WebView. So the WebView needs to wait for the CG to dequeue the waiting callbacks.
I have a Nexus 5, so that could explain why I'm facing this problem and not you (less RAM). That also makes sense with the exponential evolution of the creation time according to the markers number.
Conclusion
I think we need to reduce the memory usage and fix the memory leaks to solve this problem. My advice is to avoid new as possible and maybe use iterators.
What do you think about ?
@blckshrk If you have find any problem, please fix it, and send it as a pull request with test code.
I'm also experiencing poor performance on Android with many (~400) markers in v2. Switching from v2 to v1 cuts loading time from 19 seconds to under 2 seconds. Has there been any progress on resolving this? I'm happy to help test, but I'm pretty sure resolving it is beyond my skill. Thanks!
@bmcbride As described above, I observed the same problem, but can't found a solution...
Hey i bring my own experience in this thread. I also have some issue with v2 when i use custom marker.
Here the contexts & tests:
__Environment:__
Cordova: 6.5.0
Cordova-plugin-googlemaps: 2.0.0-beta
Android platform SDK : 6.1.2
Google Map SDK Google.android.gms:play-services-maps: 10.2.1
Phone test: Galaxy A5
__Application Context__
Angular 1.6.4 using cordova, with 2views. The home view, and the Map view. Apk size is around 10Mo.
__Test performed__
I just switch between Home view and Map view. At each switch i check memory.
Test1: not custom marker
_Test1 has 27 visibles and 39 invisibles markers during the whole test._
-> Looping between these two view seems to give almost the same results, which seems "legits" to me.
Test2: all markers are custom, size option is set to 32x32 (~10 differents png images, dimensions 36x36, between 1.5Ko and 2Ko each, and stored locally)
_Test2 has the same marker env as test1 => 27 visibles and 39 invisibles markers. Differents markers may set the same png. _
-> Looping between these two view increase memory, leading sooner or later the app to be killed by the system. So memory leaks likely occurs somewhere.
How i leave the Map view ?
I use destroy event in the Map view, in this function i do the following actions :
For each marker :
For the map :
Statements/Questions
Imho there is two distincts "statements":
So :
Anyway, any pointers/ideas from your point of view ?
Regards
@sam2x Imho, this is because the memory leaks are in the native code. So, destroy JS listeners won't clear native memory (I may said something wrong, I haven't looked at the remove() method)
Additionally, it seems that during the markers creation step some leaks appears (may some references aren't freed somewhere en lost after, waiting for a garbage collection for example).
Best,
Alex
@blckshrk thanks you for this notice. Yes, i'm aware this could be the native code guilty. However I'm trying first to take a deep look at the plugin (even if i'm not Java expert). Also It looks odd to me that so much memory is leaked from native code, in such simple "test-case", someone would have noticed if it was from native code (also i'm using last google-map sdk) ?
I'm investigating the way this plugin is dealing with BitMap (since it looks like a good culprit to me):
According the Android guideline Bitmap can "very easily exhaust an app's memory budget". They recommend to use the Glide library to "fetch, decode, and display bitmaps".
Looking at the code, i dont understand something. When creating a marker, with icon option specified, the setIcon method is called. Since we specified a size, this method call an util method resizeBitmap.
However in this resizeBitmap function we dont call "bitmap.recycle()"Â like scaleBitmapForDevice is doing.
@wf9a5m75 Isnt "bitmap.recycle()" missing here ? According my understanding from http://stackoverflow.com/questions/3823799/android-bitmap-recycle-how-does-it-work when you assign a new image, if you dont explicitely call "recycle()" the old one is still in memory.
I tried to rebuild my app without specifying the size (and let the plugin computes it via scaleBitmapForDevice which call recycle()) but result is still same as test2, so it seems to not solve the prob :/
So:
@sam2x Before asking easily, please try to debug (such as insert bitmap.recycle()) at first.
@sam2x ok, could you make another issue at once? This thread is too long.
And please make an example project that reproduce your memory issue 100%, then share it on github or bitbucket.
Is there a way to dicuss in PM about this ? i'm willing to financially contribute for your free time with this issue and make the effort/result available for the community. I know we all have priorities, and can't afford time easily.
Please send email to me (see my github profile page).
Since this thread is too long, I lock this thread.
If you have any problem with v2, please make another issue at the issue list page.
Most helpful comment
@cvaliere you should really leave this forum. I'm sick of your attitude. When this is a shitty plugin and has ton of problems for you (because it just don't fit your needs), go ahead and develop your very own version. I don't know who you think you are. When you want to build something commercial then go ahead, hire an iOS and Android developer, pay like 5000-8000 € per month and create your own, perfect, non-shitty plugin and be disrespectful with them. After that, create a Git, and share your perfect solution with everybody.
If not, shut the hell up. I really don't know how you even dare making demands on an open source project.