地图 v3.0.0 测试版的 Proguard 规则



我一直在尝试实现谷歌鼓励人们开始使用的新地图 api,但我无法克服我遇到的错误(适用于地图 v2)。

我尝试了谷歌地图示例代码中的 proguard 规则,但他们只以某种方式将 v2 规则保留在那里。他们甚至应该为 v3 工作吗?

地图类非常基础:

package com.example.test2.Fragments;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.test2.R;
import com.google.android.libraries.maps.CameraUpdateFactory;
import com.google.android.libraries.maps.GoogleMap;
import com.google.android.libraries.maps.MapView;
import com.google.android.libraries.maps.OnMapReadyCallback;
import com.google.android.libraries.maps.model.LatLng;
import com.google.android.libraries.maps.model.MarkerOptions;
public class MainMapFragment extends Fragment implements OnMapReadyCallback {
private OnFragmentInteractionListener mListener;
private MapView mapView;
private GoogleMap gMap;
private static final String MAPVIEW_BUNDLE_KEY = "MapViewBundleKey";
private final int zoomValue = 13;
public MainMapFragment() {
}
public static MainMapFragment newInstance() {
return new MainMapFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main_map, container, false);
Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY);
}
mapView = view.findViewById(R.id.map_view);
mapView.onCreate(mapViewBundle);
mapView.getMapAsync(this);
return view;
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
@Override
public void onResume() {
super.onResume();
if (mapView != null) {
mapView.onResume();
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
gMap = googleMap;
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
Bundle mapViewBundle = outState.getBundle(MAPVIEW_BUNDLE_KEY);
if (mapViewBundle == null) {
mapViewBundle = new Bundle();
outState.putBundle(MAPVIEW_BUNDLE_KEY, mapViewBundle);
}
if (mapView != null) {
mapView.onSaveInstanceState(mapViewBundle);
}
}
@Override
public void onStart() {
super.onStart();
if (mapView != null) {
mapView.onStart();
}
}
@Override
public void onStop() {
super.onStop();
if (mapView != null) {
mapView.onStop();
}
}
@Override
public void onPause() {
super.onPause();
if (mapView != null) {
mapView.onPause();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mapView != null) {
mapView.onDestroy();
}
}
@Override
public void onLowMemory() {
super.onLowMemory();
if (mapView != null) {
mapView.onLowMemory();
}
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}

我的 Proguard 规则文件:

# Jackson
-keep @com.fasterxml.jackson.annotation.JsonIgnoreProperties class * { *; }
-keep class com.fasterxsml.** { *; }
-keep class org.codehaus.** { *; }
-keepnames class com.fasterxml.jackson.** { *; }
-keepclassmembers public final enum com.fasterxml.jackson.annotation.JsonAutoDetect$Visibility { 
public static final com.fasterxml.jackson.annotation.JsonAutoDetect$Visibility *;
}
## General
-keepattributes SourceFile,LineNumberTable,*Annotation*,EnclosingMethod,Signature,Exceptions,InnerClasses
-optimizations !code/simplification/variable
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Fragment
-keep public class * extends android.support.v4.app.Fragment
# The Maps API uses custom Parcelables.
# Use this rule (which is slightly broader than the standard recommended one)
# to avoid obfuscating them.
-keepclassmembers class * implements android.os.Parcelable {
static *** CREATOR;
}
# The Maps API uses serialization.
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}

以及我在尝试在手机上打开地图时遇到的错误(小米红米 4):

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.test2, PID: 26504
java.lang.ExceptionInInitializerError
at com.google.android.libraries.maps.ex.zzd.<clinit>(GmmSettings.java:111)
at com.google.android.libraries.maps.dk.zza.zzA(DaggerMapCoreEnvironmentComponent.java:983)
at com.google.android.libraries.maps.gu.zzat.zza(RendererFactoryImpl.java:63)
at com.google.android.libraries.maps.it.zzav.zza(GoogleMapImpl.java:59)
at com.google.android.libraries.maps.it.zzcp.zza(MapViewDelegateImpl.java:3)
at com.google.android.libraries.maps.it.zzcq.zza(MapViewDelegateImpl.java:11)
at com.google.android.libraries.maps.MapView$zza.onCreate(MapView.java:6)
at com.google.android.gms.dynamic.zab.zaa(com.google.android.gms:play-services-base@@17.1.0:3)
at com.google.android.gms.dynamic.zaa.onDelegateCreated(com.google.android.gms:play-services-base@@17.1.0:4)
at com.google.android.libraries.maps.MapView$zzb.createDelegate(MapView.java:16)
at com.google.android.gms.dynamic.DeferredLifecycleHelper.zaa(com.google.android.gms:play-services-base@@17.1.0:18)
at com.google.android.gms.dynamic.DeferredLifecycleHelper.onCreate(com.google.android.gms:play-services-base@@17.1.0:22)
at com.google.android.libraries.maps.MapView.onCreate(MapView.java:26)
at d.b.a.f.t.onCreateView(MainMapFragment.java:58)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2595)
at b.j.a.i.a(FragmentManagerImpl.java:881)
at b.j.a.i.p(FragmentManagerImpl.java:1238)
at b.j.a.i.a(FragmentManagerImpl.java:1303)
at b.j.a.a.g(BackStackRecord.java:439)
at b.j.a.i.b(FragmentManagerImpl.java:2076)
at b.j.a.i.a(FragmentManagerImpl.java:1866)
at b.j.a.i.c(FragmentManagerImpl.java:1821)
at b.j.a.i.y(FragmentManagerImpl.java:1727)
at b.j.a.i$b.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:742)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5601)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:774)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)
Caused by: java.lang.NullPointerException: throw with null exception
at com.google.android.libraries.maps.ex.zzi.<init>(GmmSettings.java:2)
at com.google.android.libraries.maps.ex.zzh.<init>(GmmSettings.java:1)
at com.google.android.libraries.maps.ex.zzi.<clinit>(GmmSettings.java:16)

当我关闭 minifyEnabled 并收缩资源时,它工作得很好。

有没有人偶然发现这个?我尝试在谷歌上搜索此错误,但在任何地方都没有找到任何东西。

任何回应表示赞赏!

截至 2020/01/21 的答案准确; 在应用之前,验证在最新的 SDK 版本中是否仍需要修复。


我在当前发布的 3.0.0-beta AAR 中遇到了同样的问题。我在这里报告了这个问题。我建议的解决方法是将以下内容添加到应用的 ProGuard 配置中:

# Fix maps 3.0.0-beta crash:
-keep,allowoptimization class com.google.android.libraries.maps.** { *; }
# Fix maps 3.0.0-beta marker taps ignored:
-keep,allowoptimization class com.google.android.apps.gmm.renderer.** { *; }

希望Google团队将这些(或更精细的)规则添加到3.0.0-beta AAR中嵌入的ProGuard配置中,此时这些附加规则应该变得没有必要。不幸的是,由于 3.0.0-beta SDK 没有明显的版本版本,因此只有通过加星标并关注本答案开头链接的问题,才能知道何时发生这种情况。

在 Proguard 文件中编写此规则

-keepattributes Signature,InnerClasses
-ignorewarnings
-keepattributes *Annotation* 
-keepattributes EnclosingMethod
-keepattributes InnerClasses

并确保所有模型类都具有@Keep注释

最新更新