【问题标题】:IllegalArgumentException: Unmanaged descriptorIllegalArgumentException:非托管描述符
【发布时间】:2018-05-28 14:10:30
【问题描述】:

每当有人从 PlaceAutoComplete 片段中选择一个地点并在地图上显示标记时,我都会尝试运行地理查询。第一次工作正常。当我启动应用程序时,图标都很好,地理查询运行正常,但是当我第二次进入位置时,应用程序崩溃并显示错误 llegalArgumentException: Unmanaged descriptor下面是我想要做的。

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

 SupportPlaceAutocompleteFragment autocompleteFragment = 
 (SupportPlaceAutocompleteFragment)

 getChildFragmentManager().findFragmentById
 (R.id.place_autocomplete_fragment);

    autocompleteFragment.setOnPlaceSelectedListener(new 
  PlaceSelectionListener() {
        @Override
        public void onPlaceSelected(Place place) {
            // TODO: Get info about the selected place.

   Toast.makeText(getContext(),place.getAddress(),Toast.LENGTH_LONG).show();
            Log.i(TAG, "Place: " + place.getName());

            Double latitude1 = place.getLatLng().latitude;
            Double longitude1 =place.getLatLng().longitude;
            LatLng latLng = new LatLng(latitude1,longitude1);

            getPeople(latLng); // method to call geofire query
        }

        @Override
        public void onError(Status status) {
            // TODO: Handle the error.
            Log.i(TAG, "An error occurred: " + status);
        }
    });
    return mMainView;
}


public void getPeople(LatLng latLng1){
mMap.clear();
mMap.addCircle(new CircleOptions()
        .center(latLng1)
        .radius(2000)
        .strokeColor(Color.BLACK)
        .fillColor(0x220000FF)
        .strokeWidth(1)
 );
 DatabaseReference ref = 
 FirebaseDatabase.getInstance().getReference().child("Location");
 GeoFire geoFire = new GeoFire(ref);
 GeoQuery geoQuery = geoFire.queryAtLocation(new 
 GeoLocation(latLng1.latitude, latLng1.longitude), 2);
 geoQuery.addGeoQueryEventListener(new GeoQueryEventListener() {
    @Override
    public void onKeyEntered(final String key, GeoLocation location) {
  UIDLocation.put(key,location);
 marker.setIcon(BitmapDescriptorFactory.fromResource
 (R.drawable.ic_mapmarker2));
        markers.put(key, marker);
 for (Map.Entry<String,GeoLocation> entry : UIDLocation.entrySet())
        {
        final Marker marker = markers.get(entry.getKey());
        if (marker != null) {
        DatabaseReference mUser = 
              FirebaseDatabase.getInstance().getReference().child("People")
              .child(string);
                    mUser.addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) 
  {
                            String display_name = 
                         dataSnapshot.child("name").getValue().toString();
                            String status = 
                         dataSnapshot.child("status").getValue().toString();
                            String image = 
                          dataSnapshot.child("image").getValue().toString();
                            PeopleInfo info = new PeopleInfo();
                            info.setName(display_name);
                            info.setStatus(status);
                            info.setImage(image);
                            marker.setTag(info);
     String iconName = dataSnapshot.child("iconName")
                      .getValue().toString();
   Context context = getContext();
   int id = context.getResources().getIdentifier(iconName, "drawable", 
   context.getPackageName());
   String s = String.valueOf(id);

   Bitmap icon = BitmapFactory.decodeResource(context.getResources(),id);
   marker.setIcon(BitmapDescriptorFactory.fromResource(id));
   }

                                @Override
                                public void onCancelled(DatabaseError 
                   databaseError) {

                                }
                            });
                         }
                     }

  @Override
  public void onMapReady(final GoogleMap googleMap) {
    mMap = googleMap;
    mUiSettings = mMap.getUiSettings();
    mUiSettings.setZoomControlsEnabled(true);
    mFusedLocationClient =
            LocationServices.getFusedLocationProviderClient(getContext());

            Task task= mFusedLocationClient.getLastLocation()
            .addOnSuccessListener(getActivity(), new 
            OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {              
                    if (location != null) {
                        double latitude = location.getLatitude();
                        double longitude = location.getLongitude();
                        LatLng latLng = new LatLng(latitude, longitude);
                        myPosition = new LatLng(latitude, longitude);
                        markeroptn = new MarkerOptions();
                        markeroptn.position(myPosition);
                        markeroptn.title("You are Here");
   mMap.moveCamera(CameraUpdateFactory.newLatLng(myPosition));           
   mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myPosition,10));
                        getWorkMen(myPosition);



                    }
                }
            });

到目前为止,我从 SO 上的帖子中了解到,这是因为程序正试图在已经存在的标记上设置图标。我在 getPeople() 的开头尝试了 clear() 映射,但它仍然显示相同的错误。它第一次工作正常。我也试过 remove() 但它也不起作用。

【问题讨论】:

  • 您使用的是哪个版本的play-service-map
  • 实现 'com.google.android.gms:play-services-maps:15.0.1'
  • 我很久以前在使用版本 10 时遇到了这个问题,然后添加了更多功能并更新到版本 11,现在该异常不再抛出。但它似乎不是来自 lib 版本。我记得我对我的逻辑所做的事情是:始终保留任何标记或其他地图元素的引用。删除后,立即设置为null。更改标记图标不需要太大的位图......我现在能记住这一点
  • 我先使用了 map.clear(),然后在代码中调用了 setIcon 方法,map.clear() 是否不足以删除标记,如何将标记设置为空?我认为问题在于该方法在已经有标记的位置调用 setIcon 并且不知何故它仍然在那里,这就是它没有再次设置图标的原因。
  • 我不使用map.clear,因为对我来说这很危险。我需要保留Marker 引用,这样我就可以更改它的图标、位置...如果我调用map.clear,这意味着我所有的Marker 引用都无效。我手动调用marker.remove,然后自己将标记设置为null以将其从地图中清除,这样我就可以通过检查null来知道标记是否已被清除,并且可以避免在尝试访问已删除的标记时出现不必要的错误。

标签: android google-maps google-maps-markers illegalargumentexception


【解决方案1】:

问题可能来自您管理Marker 变量的方式。在代码中,您将 marker 变量存储为方法范围之外的全局变量。当调用map.clear() 时,它会使marker 变量无效,如果你仍然使用这个变量来设置一些东西,它可能会导致异常。用于映射keyMarkermarkers 映射也会发生同样的事情,map.clear() 不会被清除。

尝试更仔细地管理您的地图元素,独立地清除每个地图元素并避免使用map.clear()

建议方法:

创建新标记

private void addMarker(String key, LatLng latLng) {
    // Clear the current marker before add the new one
    if (marker != null) {
        marker.remove();
        marker = null;
    }

    // Store new marker to the variable
    marker = mMap.addCircle(new CircleOptions()
        .center(latLng)
        .radius(2000)
        .strokeColor(Color.BLACK)
        .fillColor(0x220000FF)
        .strokeWidth(1)
    );

    // Add to markers map if needed
    markers.put(key, marker);
}

清除所有标记(手动清除每个可用的标记变量,不要使用map.clear

public synchronized void clear() {
    // markers is the marker map
    for (Marker marker : markers.values()) {
        try {
            marker.remove();
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        }
    }

    // Clear all the marker map
    markers.clear();

    // Marker is the your global marker variable
    marker.remove();
}

【讨论】:

    猜你喜欢
    • 2017-06-13
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    相关资源
    最近更新 更多