i have around 11000 markers in markerarray list, when i try to load in map it blocks my UI, even when i use Thread and RunOnUi thread, is there any other better way i can try ??
Thread t = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < list.size(); i++) {
markerOptionList.add(new MarkerOptions().position(
new LatLng(Double.parseDouble(list.get(i)
.getLatitude()), Double
.parseDouble(list.get(i)
.getLangtitude()))).title(
list.get(i).getName() + "~"
+ list.get(i).getCity() + "~"
+ list.get(i).getSector() + "~"
+ String.valueOf(false)));
}
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
addMarker();
}
});
}
});
t.start();
add marker is my method where i added marker in map
Kindly suggest better way to implement Thanks in advance
With such amount of markers as you mentioned (11000) it is highly advisable to use Marker Clustering. You can read more about it on: https://developers.google.com/maps/documentation/android-api/utility/marker-clustering
If you still want to do this without Marker Clustering there is a simple trick that can improve user experience.
As adding a marker modifies UI - it has to be done in main UI thread. Adding too much of them at one time blocks the main thread so that the application does not respond to any user actions while it is busy with adding markers. The end user may feel like the application has hung or stopped or it can even lead to ANR
The trick is to add the markers gradually, leaving some breaks for main thread to handle other actions, so that the application remains responsive for whole the time.
I would suggest such approach:
public class DrawMarkersTask extends AsyncTask<Void, MarkerOptions, Void> {
protected void onPreExecute() {
// this method executes in UI thread
googleMap.clear(); // you can clear map here for example
}
@Override
protected Void doInBackground(Void... params) {
// this method executes in separate background thread
// you CANT modify UI here
for (int i = 0; i < list.size(); i++) {
// prepare your marker here
MarkerOptions markerOptions = new MarkerOptions().position(
new LatLng(Double.parseDouble(list.get(i)
.getLatitude()), Double
.parseDouble(list.get(i)
.getLongtitude()))).title(
list.get(i).getName() + "~"
+ list.get(i).getCity() + "~"
+ list.get(i).getSector() + "~"
+ String.valueOf(false)));
publishProgress(markerOptions); // pass it for the main UI thread for displaying
try {
Thread.sleep(50); // sleep for 50 ms so that main UI thread can handle user actions in the meantime
} catch (InterruptedException e) {
// NOP (no operation)
}
}
return null;
}
protected void onProgressUpdate(MarkerOptions... markerOptions) {
// this executes in main ui thread so you can add prepared marker to your map
googleMap.addMarker(markerOptions[0]);
}
protected void onPostExecute(Void result) {
// this also executes in main ui thread
}
}
Note that DrawMarkersTask must be inner class of your Activity so it has direct access to UI. If you would like to make it separate class follow this: android asynctask sending callbacks to ui
Then you draw markers without blocking main thread like this:
DrawMarkersTask drawMarkersTask = new DrawMarkersTask();
drawMarkersTask.execute();
NOTE: This is just a trick. It has nothing to do with reducing or optimising complexity of this problem it just hides it from user by spreading operations in time. Yet still such approach is sometimes an acceptable compromise.
Loading 11000 makers is a very heavy workload for the device. Even you can add all of them to the map, when you zoom out, you will probably face the same problem. There is a official Google article about various advanced marker management techniques. Use one of them to show only necessary markers instead of all of them.
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