18

使用 2 个简单的活动。第一个活动只包含一个按钮来启动第二个包含地图的活动:

主要活动:

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

public void goToMap(View view){ //This is just the onClick method for the button
    Intent intent=new Intent( this, BigMapTest.class);
    startActivity(intent);
}

地图活动:

public class BigMapTest extends FragmentActivity {
SupportMapFragment mapFragment;
GoogleMap map;

@Override
protected void onCreate(Bundle arg0) {
    // TODO Auto-generated method stub
    super.onCreate(arg0);

    setContentView(R.layout.travel_diary_big_map);

    mapFragment=(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.big_map);
    map=mapFragment.getMap();

}

地图活动的 XML 布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<fragment
        android:id="@+id/big_map"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        class="com.google.android.gms.maps.SupportMapFragment"  
        />

现在,当我运行这段代码时,按下按钮移动到带有地图的 Activity,然后按下返回到第一个 Activity ......然后重复这个过程,我可以看到堆的大小每次都在增加,直到达到这是极限,然后它开始夹紧。如果您在地图(即缩放)方面搞得更糟一点,此时我可能会遇到 OOM 异常。

01-25 16:10:13.931: D/dalvikvm(21578): GC_FOR_ALLOC 释放 1898K, 7% 空闲 45859K/49187K, 暂停 204ms 01-25
16:10:14.671: I/dalvikvm-heap(21578): 钳制目标 GC堆从 52.724MB 到 48.000MB 01-25
16:10:14.671:D/dalvikvm(21578):GC_CONCURRENT 释放 2534K,6% 空闲 46554K/49187K,暂停 3ms+14ms
01-25 16:10:15.372:I/dalvikvm -heap(21578): 将目标 GC 堆从 52.979MB 钳制到 48.000MB 01-25
16:10:15.382: D/dalvikvm(21578): GC_CONCURRENT freed 2273K, 5% free 46815K/49187K, paused 3ms+15ms
01-25 16:10:15.622: I/dalvikvm-heap(21578): 将目标 GC 堆从 52.604MB 钳制到 48.000MB 01-25
16:10:15.622: D/dalvikvm(21578): GC_FOR_ALLOC 释放 657K,6% 释放 46431K/ 49187K,暂停 202ms
01-25 16:10:16.203:I/dalvikvm-heap(21578):将目标 GC 堆从 52.959MB 钳制到 48.000MB 01-25
16:10:16.203:D/dalvikvm(21578):GC_FOR_ALLOC 释放 1469K,5%免费 46796K/49187K,暂停 217 毫秒 01-25
16:10:16.203:I/dalvikvm-heap(21578):强制收集软引用以分配 278744 字节
01-25 16:10:16.423:I/dalvikvm-heap(21578 ): 将目标 GC 堆从 52.952MB 钳制到 48.000MB 01-25
16:10:16.423: D/dalvikvm(21578): GC_BEFORE_OOM 释放 9K, 5% free 46786K/49187K, 暂停 219ms 01-25
16:10:16.423: E/dalvikvm-heap(21578):278744 字节分配内存不足。

任何建议/帮助将不胜感激。

4

4 回答 4

8

从一些基本的 MAT 侦查中我可以看出,您所看到的是由 Maps V2 维护的下载地图数据的缓存。如果您平移和缩放很多,缓存似乎更大。如果您离开地图并稍后返回新地图,缓存会缩小。我无法从 N 次启动示例应用程序的地图活动中获得 N 个缓存,并且缓存大小会根据用户的操作而起伏。

唉,这个缓存是不可配置的,AFAIK,就它有多大,当它被清除时,它是否溢出到磁盘等方面。

因此,默认情况下,您所能做的就是留出一部分健康的堆空间供 Maps V2 使用,并采取措施保持在这个较小的堆子集中。

如果您想进行试验,您可以尝试调用clear(),GoogleMaponLowMemory()您的SupportMapFragment, 以查看是否有任何帮助减少此缓存大小。

于 2013-01-26T15:10:53.717 回答
2

Android 开发者下午 5:10 - Google+ 页面

我们正在推出 Google Play 服务 v3.0,其中引入了 Google+ 登录和 Google Maps Android API 改进。

自 2013 年 2 月 26 日起, gmaps-api-issues 页面上也描述了此问题,现在已由当前的Google API 更新修复。

于 2013-02-26T21:58:44.303 回答
1

我也有完全一样的问题。每次托管 V2 地图的活动开始时,内存都会增加。即使活动完成,它也不会被释放。

所以解决方法是重用该活动。singleTask在清单中制作活动,而不是finish()使用它moveTaskToBack(true);

于 2013-01-30T09:13:10.223 回答
-1

在您的布局中使用它:

<LinearLayout
        android:id="@+id/map_container2"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_weight="35.22"
        android:orientation="horizontal" >

        <fragment
            android:id="@+id/map1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            class="com.google.android.gms.maps.SupportMapFragment"
            map:cameraTargetLat="40.72"
            map:cameraTargetLng="-74.00"
            map:cameraZoom="8" />
    </LinearLayout>

而这段代码:

onCreate{
   setUpMapIfNeeded();
}

private void setUpMapIfNeeded() {
        // TODO Auto-generated method stub
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map1))
                    .getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                setUpMap();
            }
        }
    }

private void setUpMap() {
        // TODO Auto-generated method stub
         // Hide the zoom controls as the button panel will cover it.
        mUiSettings = mMap.getUiSettings();
 // Enables/disables zoom gestures (i.e., double tap, pinch & stretch).
        mMap.getUiSettings().setZoomGesturesEnabled(false);
// Enables/disables scroll gestures (i.e. panning the map).
        mMap.getUiSettings().setScrollGesturesEnabled(false);
 // Enables/disables the compass (icon in the top left that indicates the orientation of the
        // map).
        mMap.getUiSettings().setCompassEnabled(false);
        // Add lots of markers to the map.
        addMarkersToMap();

        // Pan to see all markers in view.
        // Cannot zoom to bounds until the map has a size.
        final View mapView = getSupportFragmentManager().findFragmentById(R.id.map1).getView();
        if (mapView.getViewTreeObserver().isAlive()) {
            mapView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                @SuppressLint("NewApi") // We check which build version we are using.
                @Override
                public void onGlobalLayout() {
                    LatLngBounds bounds = new LatLngBounds.Builder()
                            .include(WOODS)
                            .build();
                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                      mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    } else {
                      mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    }
                    mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
                }
            });
        }
    }

private void addMarkersToMap() {
        // TODO Auto-generated method stub
         // Uses a colored icon.
        mWoods = mMap.addMarker(new MarkerOptions()
                .position(WOODS)
                .title("Woods")
                .snippet("R. Quatá, 1016, Vila Olimpia - (11) 3849-6868")
                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
    }
于 2013-01-25T14:44:52.350 回答