Saya menggunakan peta Google dengan penanda khusus di proyek saya, di mana setiap penanda perlu disetel dengan tampilan khusus, untuk tujuan berbeda seperti titik jalan dengan polyline dan penanda untuk mengidentifikasinya, poligon dengan penanda, dll. Sekarang ketika penanda ini lebih dari 1000, maka bitmap gagal dimuat ke dalam Peta dan OOM terlempar.
Saya telah menggunakan sumber daya dapat digambar untuk vektor sebagai identitas penanda dan tampilan teks normal untuk meratakannya, membuat bitmap membutuhkan gambar 180*210,
Bagaimana saya bisa mengelolanya secara efisien tanpa masalah lagging dan OOM?
ini kodenya: Ini untuk membaca lokasi dari Array allGlobalPoints dan membedakannya serta memplotnya.
mMap.clear();
allpointPlotterThreadRunning = true;
switchTospecific = true;
final String POINTS = "points";
final String POIS = "pois";
final String FAILSAFE = "failsafe";
final String POLYGON = "polygon";
final String LASTPOLYGON = "lastpolygon";
allMapPointPlotter = new AsyncTask<Void, Object, Void>() {
ProgressDialog pgbarLoading;
PolylineOptions polyline;
PolygonOptions plogon;
@Override
protected void onPreExecute() {
super.onPreExecute();
final View tiltleView = ((LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.progress_dialog_title_background, null);
OpenSansRegularTextView tiltle = (OpenSansRegularTextView) tiltleView.findViewById(R.id.title_text);
tiltle.setText("UAV Editor");
pgbarLoading = new ProgressDialog(getActivity());
pgbarLoading.setCancelable(false);
pgbarLoading.setMessage("" + getActivity().getString(R.string.please_wait));
pgbarLoading.setCustomTitle(tiltleView);
pgbarLoading.show();
markerPlottedList = new ArrayList<>();
markerOnQueue = new ArrayList<>();
((DashboardActivity) getActivity()).setZoomOut();
}
@Override
protected void onCancelled() {
super.onCancelled();
allpointPlotterThreadRunning = false;
}
@Override
protected Void doInBackground(Void... voids) {
try {
if (allpointPlotterThreadRunning) {
if (allGlobalPoints.size() > 0) {
for (int global = 0; global < allGlobalPoints.size(); global++) {
if (allpointPlotterThreadRunning) {
//getting first object containing all points data
AllGlobalPointsArrayData globalDataObject = allGlobalPoints.get(global); //This is the object of the position that contains all 5 data
if (globalDataObject.getPointsDataArray() != null && globalDataObject.getPointsDataArray().size() > 0) {
ArrayList<RoutePointCoordinatesDataType> innerarraylist = globalDataObject.getPointsDataArray();
for (int i = 0; i < innerarraylist.size(); i++) {
if (allpointPlotterThreadRunning) {
if (i == (innerarraylist.size() - 1)) {
publishProgress(
POINTS,
Double.parseDouble(innerarraylist.get(i).getCoordinatesLatitude()),
Double.parseDouble(innerarraylist.get(i).getCoordinatesLongitude()),
i,
"" + innerarraylist.get(i).getTag(),
innerarraylist.get(i).getHeadingAngle(),
true
);
} else {
publishProgress(
POINTS,
Double.parseDouble(innerarraylist.get(i).getCoordinatesLatitude()),
Double.parseDouble(innerarraylist.get(i).getCoordinatesLongitude()),
i,
"" + innerarraylist.get(i).getTag(),
innerarraylist.get(i).getHeadingAngle(),
false
);
}
} else {
break;
}
}
}
if (globalDataObject.getPoiDataArray() != null && globalDataObject.getPoiDataArray().size() > 0) {
ArrayList<RoutePointCoordinatesDataType> innerList = globalDataObject.getPoiDataArray();
if (innerList != null && innerList.size() > 0) {
for (int i = 0; i < innerList.size(); i++) {
if (allpointPlotterThreadRunning) {
publishProgress(
POIS,
Double.parseDouble(innerList.get(i).getCoordinatesLatitude()),
Double.parseDouble(innerList.get(i).getCoordinatesLongitude()),
i,
"" + innerList.get(i).getTag()
);
} else {
break;
}
}
}
}
if (globalDataObject.getFailsafeDataArray() != null && globalDataObject.getFailsafeDataArray().size() > 0) {
ArrayList<RoutePointCoordinatesDataType> innerArray = globalDataObject.getFailsafeDataArray();
if (innerArray != null && innerArray.size() > 0) {
for (int i = 0; i < innerArray.size(); i++) {
if (allpointPlotterThreadRunning) {
publishProgress(
FAILSAFE,
Double.parseDouble(innerArray.get(i).getCoordinatesLatitude()),
Double.parseDouble(innerArray.get(i).getCoordinatesLongitude()),
i,
"" + innerArray.get(i).getTag()
);
} else {
break;
}
}
}
}
if (globalDataObject.getPolygonLastUsedDataArray() != null && globalDataObject.getPolygonLastUsedDataArray().size() > 0) {
ArrayList<RoutePointCoordinatesDataType> innerArray = globalDataObject.getPolygonLastUsedDataArray();
if (innerArray != null && innerArray.size() > 0) {
for (int i = 0; i < innerArray.size(); i++) {
if (allpointPlotterThreadRunning) {
if (i == (innerArray.size() - 1)) {
publishProgress(
LASTPOLYGON,
Double.parseDouble(innerArray.get(i).getCoordinatesLatitude()),
Double.parseDouble(innerArray.get(i).getCoordinatesLongitude()),
i,
"" + innerArray.get(i).getTag(),
true
);
} else {
publishProgress(
LASTPOLYGON,
Double.parseDouble(innerArray.get(i).getCoordinatesLatitude()),
Double.parseDouble(innerArray.get(i).getCoordinatesLongitude()),
i,
"" + innerArray.get(i).getTag(),
false
);
}
} else {
break;
}
}
}
}
if (globalDataObject.getPolygonLastUsedDataArray() == null || globalDataObject.getPolygonLastUsedDataArray().size() == 0) {
ArrayList<RoutePointCoordinatesDataType> innerArray = globalDataObject.getPolygonDataArray();
if (innerArray != null && innerArray.size() > 0) {
for (int i = 0; i < innerArray.size(); i++) {
if (allpointPlotterThreadRunning) {
if (i == (innerArray.size() - 1)) {
publishProgress(
POLYGON,
Double.parseDouble(innerArray.get(i).getCoordinatesLatitude()),
Double.parseDouble(innerArray.get(i).getCoordinatesLongitude()),
i,
"" + innerArray.get(i).getTag(),
true
);
} else {
publishProgress(
POLYGON,
Double.parseDouble(innerArray.get(i).getCoordinatesLatitude()),
Double.parseDouble(innerArray.get(i).getCoordinatesLongitude()),
i,
"" + innerArray.get(i).getTag(),
false
);
}
} else {
break;
}
}
}
}
} else {
break;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Object... values) {
super.onProgressUpdate(values);
if (allpointPlotterThreadRunning) {
String tagmarker = (String) values[0];
int innerCounter = (Integer) values[3];
if (tagmarker.equalsIgnoreCase(POINTS)) {
if (innerCounter == 0) {
polyline = new PolylineOptions();
polyline.width(4);
polyline.color(Color.parseColor("#425fa9"));
polyline.geodesic(true);
}
polyline.add(
new LatLng(
(Double) values[1],
(Double) values[2]
)
);
if ((Double) values[5] != 400) {
createMarker(
mMap,
(Double) values[1],
(Double) values[2],
innerCounter,
(String) values[4],
(Double) values[5]
);
} else {
createMarker(
mMap,
(Double) values[1],
(Double) values[2],
innerCounter,
(String) values[4],
400
);
}
if ((Boolean) values[6]) {
mMap.addPolyline(polyline);
}
} else if (tagmarker.equalsIgnoreCase(POIS)) {
createMarkerPoi(
mMap,
(Double) values[1],
(Double) values[2],
innerCounter,
(String) values[4]
);
} else if (tagmarker.equalsIgnoreCase(FAILSAFE)) {
createMarkerFailsafe(
mMap,
(Double) values[1],
(Double) values[2],
innerCounter,
(String) values[4]
);
} else if (tagmarker.equalsIgnoreCase(POLYGON)) {
if (innerCounter == 0) {
plogon = new PolygonOptions();
plogon.fillColor(Color.parseColor("#20ff1a1a"));
plogon.strokeWidth((float) 5.1)
.strokeColor(Color.parseColor("#30ff1a1a"));
}
createMarkerPolygon(
mMap,
(Double) values[1],
(Double) values[2],
innerCounter,
(String) values[4]
);
plogon.add(new LatLng(
(Double) values[1],
(Double) values[2]
));
if ((Boolean) values[5]) {
mMap.addPolygon(plogon);
}
} else if (tagmarker.equalsIgnoreCase(LASTPOLYGON)) {
if (innerCounter == 0) {
plogon = new PolygonOptions();
plogon.fillColor(Color.parseColor("#20ff1a1a"));
plogon.strokeWidth((float) 5.1)
.strokeColor(Color.parseColor("#30ff1a1a"));
}
createMarkerPolygon(
mMap,
(Double) values[1],
(Double) values[2],
innerCounter,
(String) values[4]
);
plogon.add(new LatLng(
(Double) values[1],
(Double) values[2]
));
if ((Boolean) values[5]) {
mMap.addPolygon(plogon);
}
}
}
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
pgbarLoading.dismiss();
allpointPlotterThreadRunning = false;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Untuk membuat marker dan bitmap, fungsi berikut digunakan:-> memoryCacheData digunakan sebagai daftar lrucache untuk akses cepat ke bitmap
protected void createMarker(GoogleMap map, double latitude, double longitude, int inner, String outer, double angle) {
try {
Bitmap resultantBitmap = null;
if (((DashboardActivity) getActivity()).memoryCacheData != null && ((DashboardActivity) getActivity()).memoryCacheData.size() > 0) {
resultantBitmap = ((DashboardActivity) getActivity()).memoryCacheData.get(latitude + "/" + longitude + "-OwnTab-" + inner + "|" + outer);
if (resultantBitmap == null) {
resultantBitmap = getMarkerBitmapFromView("P" + (inner + 1), "P", angle);
((DashboardActivity) getActivity()).memoryCacheData.put(latitude + "/" + longitude + "-OwnTabMarker-" + inner + "|" + outer, resultantBitmap);
}
} else {
resultantBitmap = getMarkerBitmapFromView("P" + (inner + 1), "P", angle);
((DashboardActivity) getActivity()).memoryCacheData.put(latitude + "/" + longitude + "-OwnTabMarker-" + inner + "|" + outer, resultantBitmap);
}
map.addMarker(new MarkerOptions()
.position(new LatLng(latitude, longitude))
.anchor(0.5f, 0.5f)
.title("" + outer)
.icon(BitmapDescriptorFactory.fromBitmap(resultantBitmap))
);
} catch (Exception e) {
e.printStackTrace();
}
}
Tolong bantu saya cara mengelola bitmap tanpa membekukan aplikasi dan menghindari pengecualian kehabisan memori, dan bagaimana saya bisa mengelola penanda sebanyak itu dengan tampilan khusus.