【问题标题】:Android out memory exception in map地图中的Android内存异常
【发布时间】:2016-05-24 12:46:53
【问题描述】:

在我的 Android 应用程序中,我每 10 秒调用一次服务器请求,并使用标记更新地图中的结果(创建位图,我的标记具有图像和文本)。我使用Android map utils library 创建我的布局的位图,这工作正常,但一段时间后我的力量关闭了内存不足的问题。

Note:
My marker has image and text like a layout.
its updates with dynamic result by every 10 seconds.

我使用了library中的两个主要类

1.BubbleDrawable 2.IconGenerator,我已经使用这两个类来创建我的布局的位图。

在我的地图活动中,我每 10 秒调用一次库并使用自定义标记刷新地图。

代码:

public class MainActivity extends Activity{

 private IconGenerator  icGen ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         icGen = new IconGenerator(this);
         serverResponse(); // this method call every 10 seconds
    } // onCreate ends here.

    void updateResult(String placeName){
         markerPin = googleMap.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(icGen.makeIcon(placeName))) // dynamic name 
             .position(markerLatLng).anchor(0.5f, 1.0f)); // I got out of memory exception here
        ....
        googleMap.addMarker(markerPin);     
    }

    void serverResponse(){
        JSONArray arr = new JSONArray(serverResponse);
        for(int i=0;i<all.length();i++){
          name = arr.getJSONObject.getStrig(name);
          updateResult(name);
        }
    }
}

我不知道如何解决这个问题,请帮助我。

【问题讨论】:

  • 您是在不再需要标记时删除标记,还是继续添加新标记而不删除旧标记?
  • 每次从服务器获取新数据时,我都会检查旧数据和新数据,如果发现任何地方的修改,那么我将删除旧标记并创建新位图并用作标记,未更改的地方标记不会被删除。
  • 那么我会说您的OutOfMemory 是由于在您的地图中保留了大量标记造成的。您真的不需要维护地图中的所有标记(这会破坏性能),您只需要显示可见的标记。例如,您可以删除所有标记 (map.clear()) 并在 onCameraChange 事件中添加可见标记。为此,您需要维护一个结构来存储您从服务中下载的位置,并检查这些位置是否在可见视口中。
  • 您能否提供示例以显示可见区域的标记并将标记隐藏到不可见区域?

标签: android google-maps bitmap android-memory


【解决方案1】:

来自cmets:

我会说你的 OutOfMemory 是由于保留了大量的 地图中的标记。你真的不需要维护所有的标记 在您的地图中(它会破坏性能),您只需要显示 可见的。因此,例如,您可以删除所有标记 (map.clear()) 并在 onCameraChange 事件中添加可见的。到 这样做,您将需要维护一个结构来存储位置 您从您的服务下载并检查这些地点是否在 可见视口。

这是一个示例,每次相机更改时都会清除地图并添加所有可见标记(我只显示相关代码。请注意它未经测试):

public class MainActivity extends Activity implements GoogleMap.OnCameraChangeListener, GoogleMap.OnMapReadyCallback {
    private GoogleMap googleMap;
    private List<Place> places = new ArrayList<>();

    // ...

    void serverResponse() {
        JSONArray arr = new JSONArray(serverResponse);
        for (int i = 0; i < all.length(); i++) {
            name = arr.getJSONObject.getStrig(name);

            // TODO: Get the LatLong

            // Add a new Place to the list 
            places.add(new Place(name, latLng));
        }
    }

    @Override
    public void onCameraChange(final CameraPosition cameraPosition) {
        // Clear the map to avoid keeping tons of markers
        googleMap.clear();

        // Find the current visible region
        final LatLngBounds bounds = googleMap.getProjection()
                .getVisibleRegion().latLngBounds;

        // Draw the visible markers
        for (Place place : places) {
            if (bounds.contains(place.getLatLng())) {
                googleMap.addMarker(new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(icGen.makeIcon(place.getName())))
                        .position(place.getLatLng()).anchor(0.5f, 1.0f));
            }
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        this.googleMap = googleMap;
        googleMap.setOnCameraChangeListener(this);
    }

    private class Place {
        private String name;
        private LatLng latLng;

        public Place(String name, LatLng latLng) {
            this.name = name;
            this.latLng = latLng;
        }

        public String getName() {
            return name;
        }

        public void setName(final String name) {
            this.name = name;
        }

        public LatLng getLatLng() {
            return latLng;
        }

        public void setLatLng(final LatLng latLng) {
            this.latLng = latLng;
        }
    }
}

也许您需要改进将List&lt;Place&gt; 更改为Map&lt;String, Place&gt; 的代码,以确保您不会两次添加给定地点。

【讨论】:

  • 我已经使用了上述逻辑,但是在放大或缩小时会调用 onCameraChange 方法。我怎样才能防止这种情况发生?
  • onCameraChange 收到CameraPosition,您可以从那里获得target。您需要将当前的target 与旧的进行比较(您需要保存它)并在缩放/平移时采取不同的操作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
  • 2012-10-24
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多