【问题标题】:NoSuchFieldError: No static field MapAttrs of type when Using MapFragment with Play Services 6.5NoSuchFieldError:在使用 MapFragment 和 Play Services 6.5 时没有类型的静态字段 MapAttrs
【发布时间】:2014-12-09 11:28:11
【问题描述】:

也许我在这里遗漏了一些东西,但我无法在 Play Services 6.5 中使用新的 Maps only 依赖项

我得到以下异常:

java.lang.NoSuchFieldError: No static field MapAttrs of type 
    [I in class Lcom/google/android/gms/R$styleable; or its superclasses 
    (declaration of 'com.google.android.gms.R$styleable' appears in 
    /data/app/com.kaching.merchant.dev1-1/base.apk)
        at com.google.android.gms.maps.GoogleMapOptions
            .createFromAttributes(Unknown Source)
        at com.google.android.gms.maps.SupportMapFragment
            .onInflate(Unknown Source)

清单:

<meta-data android:name="com.google.android.gms.version"
  android:value="@integer/google_play_services_version" />

<meta-data
  android:name="com.google.android.maps.v2.API_KEY"
  android:value="my-awesome-key"/>


<uses-permission 
  android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>

Gradle 文件:

compile 'com.google.android.gms:play-services-maps:6.5.+'
compile 'com.android.support:support-v4:21.0.2'

布局:

<fragment
   android:id="@+id/map"
   android:name="com.google.android.gms.maps.MapFragment"
   android:layout_width="match_parent"
   android:layout_height="match_parent"/>

这是坏了还是我做错了什么?

完整的捆绑包让我超过了 dex 限制,我不想使用 multidex

【问题讨论】:

  • 问题是com.google.android.gms.R$styleable.MapAttrs,但生成的地图R文件有不同的包com.google.android.gms.maps.R$styleable.MapAttrs似乎与那些版本的“granualr取决于”错误,现在Selectively compiling APIs不可用......
  • 我确实设法让它工作(apk 大小:maps+base 1,9 MB 整个 gms:2,5MB)... 步骤:1. 将地图和基本 aar 文件复制到 libs 文件夹项目 2. 在 gradle 中添加对 em 的依赖而不是原来的 3. 在 maps.aar 中修改 AndroidManifest.xml 中的包(删除:“.maps”) 4. 禁用enforceUniquePackageName(将其设置为false)......换句话说:不值得花时间......我们必须等到谷歌修复它
  • 好的,所以这实际上是坏的。我很困惑,谷歌显然没有人在发布之前考虑过对其进行测试。
  • 好的,我做了一个错误报告:code.google.com/p/android/issues/…
  • 对于未来的读者来说,似乎只是从 xml 膨胀地图片段(或我的情况下的地图视图)会导致这个问题。如果您在代码中实例化片段(或视图),一切都很好。

标签: android google-play-services google-maps-android-api-2 android-gradle-plugin


【解决方案1】:

通过 SDK 管理器将您的 Google 存储库 更新到版本 15 应该可以解决问题并消除对变通方法的需求。需要清理项目。

issue 7432中也提到了这一点。

【讨论】:

  • 我的问题是“引起:java.lang.NoSuchFieldError: com.google.android.gms.R$styleable.AdsAttrs”,这解决了。谢谢
  • 更新 Google 存储库后,我需要 gradle clean,然后是 gradle build。我认为当您导入新的依赖项或更新时,Android Studio 在正确查找资源方面往往会有些滞后。
  • 我在 xamarin 平台上开发,我遇到了同样的问题。清洁液解决了我的问题。
【解决方案2】:

临时解决方案

用 FrameLayout 容器替换 xml 地图片段

<FrameLayout
    android:id="@+id/map_container"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="0dp"
/>
<!--<fragment android:id="@+id/map"-->
<!--android:layout_weight="2"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="0dp"-->
<!--android:name="com.google.android.gms.maps.SupportMapFragment"/>-->

在代码中创建片段并替换容器

SupportMapFragment supportMapFragment = SupportMapFragment.newInstance();
getSupportFragmentManager().beginTransaction().replace(R.id.map_container,supportMapFragment).commit();

//this you should do anyway
supportMapFragment.getMapAsync(new OnMapReadyCallback() {
    @Override
    public void onMapReady(GoogleMap googleMap) {
        //setup map - optional
        UiSettings settings = googleMap.getUiSettings();
        settings.setCompassEnabled(false);
        settings.setZoomControlsEnabled(false);
        settings.setAllGesturesEnabled(true);
        settings.setMyLocationButtonEnabled(true);
    }
});

请注意,上述操作是在 Activity 中的“onCreate”中完成的,没有任何其他片段,因此请确保使事务适应您的生命周期和逻辑。

【讨论】:

  • 天哪,那个 OnMapReadyCallback,难怪我的地图总是为空。
【解决方案3】:

在 Google 决定修复此问题之前,我发现了一个“hacky”修复程序以使其与您的应用程序一起工作:

将此添加到您的 app gradle 脚本中:

afterEvaluate {
    def pattern = ~/process(.*)Resources/
    tasks.matching { pattern.matcher(it.name).find() }.each {
        def matcher = pattern.matcher(it.name)
        matcher.find()
        def buildType = matcher.group(1)
        buildType = buildType.substring(0, 1).toLowerCase() + buildType.substring(1)
        def rDirectory = "$project.buildDir/generated/source/r/$buildType"
        it << {
            def badFile = file("$rDirectory/com/google/android/gms/R.java")
            def goodFile = file("$rDirectory/com/google/android/gms/maps/R.java")
            if (badFile.exists() && goodFile.exists()) {
                badFile.text = goodFile.text.replaceAll('com.google.android.gms.maps', 'com.google.android.gms')
            }
        }
    }
}

【讨论】:

  • 请注意,这是一个糟糕的修复,如果您使用多个 play-services-* 子库,它将无法扩展。我们将妥善解决问题。
  • @XavierDucrohet:是的!合并它们太多了。我以为你会在这方面工作……但很高兴看到你在追捕。我太兴奋了,想试试你们的新图书馆,呵呵。不打算用于最终修复:)
  • 对我不起作用。我还需要做什么吗?
  • @PhilippE.:你是把它放在app gradle 中而不是项目 gradle 中吗?
  • app gradle,在 android 块下面
【解决方案4】:

我认为您在库和模块中都有相同名称的布局或 使用重复的资源 ID 膨胀多个 xml 布局。

在 play-services-lib 中找到 map_attrs 并替换为以下代码:

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <declare-styleable name="MapAttrs">
    <attr name="mapType" format="enum">
      <enum name="none" value="0"/>
      <enum name="normal" value="1"/>
      <enum name="satellite" value="2"/>
      <enum name="terrain" value="3"/>
      <enum name="hybrid" value="4"/>



    </attr>
    <attr name="cameraBearing" format="float"/>
    <attr name="cameraTargetLat" format="float"/>
    <attr name="cameraTargetLng" format="float"/>
    <attr name="cameraTilt" format="float"/>
    <attr name="cameraZoom" format="float"/>
    <attr name="liteMode" format="boolean"/>



    <attr name="uiCompass" format="boolean"/>
    <attr name="uiRotateGestures" format="boolean"/>
    <attr name="uiScrollGestures" format="boolean"/>
    <attr name="uiTiltGestures" format="boolean"/>
    <attr name="uiZoomControls" format="boolean"/>
    <attr name="uiZoomGestures" format="boolean"/>
    <attr name="useViewLifecycle" format="boolean"/>
    <attr name="zOrderOnTop" format="boolean"/>
    <attr name="uiMapToolbar" format="boolean"/>
    <attr name="ambientEnabled" format="boolean"/>
  </declare-styleable>

</resources>

【讨论】:

  • 谢谢,您的回答也解决了我的问题 :) 我认为您在库和模块中都有相同名称的布局,或者使用重复的资源 ID 膨胀多个 xml 布局。
【解决方案5】:

终于找到原因了。如果你有为了自己的 Eclipse 利益而绑架 aar 文件的习惯(我不会在这里教你怎么做,因为这不是 Android Studio 的方式),你需要移动 ma​​ps_attrs.xml 文件在 play-services-base res/values 文件夹中。这将使属性和生成的 R.class 文件在地图库所期望的类路径上对齐。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多