【问题标题】:Android - EBADF (Bad file number) OnClickInfoMarkerAndroid - EBADF(错误文件号)OnClickInfoMarker
【发布时间】:2015-02-19 21:21:27
【问题描述】:

我已经搜索了相关问题,但找不到。我创建了一个显示图片、名称和地址的 InfoWindowMarker。然后我创建 OnInfoWindowClickListener,它将显示所选标记的纬度和经度。但是当我单击信息窗口时,我收到了这个错误消息。

Logcat:

com.xxxxxxxx.xxxxxxxxxx E/Zygote: Zygote: 错误关闭描述符 libcore.io.ErrnoException:关闭失败:EBADF(错误文件号) 在 libcore.io.Posix.close(本机方法) 在 libcore.io.BlockGuardOs.close(BlockGuardOs.java:75) 在 com.android.internal.os.ZygoteInit.closeServerSocket(ZygoteInit.java:221) 在 com.android.internal.os.ZygoteConnection.handleChildProc(ZygoteConnection.java:879) 在 com.android.internal.os.ZygoteConnection.runOnce(ZygoteConnection.java:242) 在 com.android.internal.os.ZygoteInit.runSelectLoop(ZygoteInit.java:713) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:649) 在 dalvik.system.NativeStart.main(Native Method)

InfoWindowAdapter:

public GoogleMap.InfoWindowAdapter CustomMarkerInfo = new GoogleMap.InfoWindowAdapter() {
    @Override
    public View getInfoWindow(Marker marker) {
        ViewGroup viewGroup = (ViewGroup)getLayoutInflater().inflate(R.layout.custom_info_window, null);
        ImageView ivRow = (ImageView)viewGroup.findViewById(R.id.ivRowImage);
        TextView locationName = (TextView)viewGroup.findViewById(R.id.tvRowTitle);
        TextView locationAddress = (TextView)viewGroup.findViewById(R.id.tvRowTitle2);
        Bitmap locationImage;

        locationName.setText(marker.getTitle());
        locationAddress.setText(marker.getSnippet());
        URL imageURL;
        try {
            imageURL = new URL(markerInfo.get(marker.getId()));
            locationImage = BitmapFactory.decodeStream(imageURL.openConnection().getInputStream());
            ivRow.setImageBitmap(locationImage);
        }catch (Exception e){
            e.printStackTrace();
        }
        return viewGroup;
    }

    @Override
    public View getInfoContents(Marker marker) {return null;}
};

OnInfoWindowClickListener:

 private GoogleMap.OnInfoWindowClickListener onInfoWindowClickListener = new GoogleMap.OnInfoWindowClickListener() {
    @Override
    public void onInfoWindowClick(Marker marker) {
        LatLng myLatLng = myLatLng();
        Toast.makeText(getApplicationContext(),myLatLng.toString(),Toast.LENGTH_LONG).show();
    }
};

private final LocationListener locationListener = new LocationListener() {
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {}

    @Override
    public void onProviderEnabled(String provider) {}

    @Override
    public void onProviderDisabled(String provider) {}

    @Override
    public void onLocationChanged(Location newLocation) {

    }
};

private LatLng myLatLng(){
    LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    String provider;
    Location location;
    LatLng myLatLng = null;

    if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
        provider = LocationManager.GPS_PROVIDER;
        Toast.makeText(getApplicationContext(),"GPS tidak aktif.",Toast.LENGTH_LONG).show();
    }else if(locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
        provider = LocationManager.NETWORK_PROVIDER;
    }else{
        provider = LocationManager.PASSIVE_PROVIDER;
    }


    if(locationManager.getLastKnownLocation(provider) == null){
        locationManager.requestLocationUpdates(provider,2000,10,locationListener);
        location = locationManager.getLastKnownLocation(provider);
        if(location == null){
            Toast.makeText(getApplicationContext(),"Tidak dapat menemukan lokasi saat ini, coba lagi.",Toast.LENGTH_LONG).show();
        }else{
            location = locationManager.getLastKnownLocation(provider);
            myLatLng = new LatLng(location.getLatitude(),location.getLongitude());
        }
    }else{
        location = locationManager.getLastKnownLocation(provider);
        myLatLng = new LatLng(location.getLatitude(),location.getLongitude());
    }
    return myLatLng == null ? myLatLng() : myLatLng;
}

感谢您的任何解决方案。

更新:从加载的 JSON 创建的标记。如果它可能导致此问题。

【问题讨论】:

    标签: java android google-maps


    【解决方案1】:

    这可能是线程问题。您的 viewGroup 在从 URL 加载图像之前返回。一个简单的解决方法是使用第三方图片加载库Picasso

    示例代码:

     ImageView imageView = (ImageView)myContentsView.findViewById(R.id.ivRowImage);
     if (not_first_time_showing_info_window) {
         Picasso.with(getApplicationContext()).load("YOUR_IMG_URL").into(imageView);
     } else { // if it's the first time, load the image with the callback set
         not_first_time_showing_info_window=true;
         Picasso.with(getApplicationContext()).load("YOUR_IMG_URL").into(imageView,new InfoWindowRefresher(marker));
     }
    

    然后你可以有一个私有的辅助方法来确保在第一次点击中显示异步:

     private class InfoWindowRefresher implements Callback {
            private Marker markerToRefresh;
    
            private InfoWindowRefresher(Marker markerToRefresh) {
                this.markerToRefresh = markerToRefresh;
            }
    
            @Override
            public void onSuccess() {
                markerToRefresh.showInfoWindow();
            }
    
            @Override
            public void onError() {}
        }
    

    完整实现可以参考这个GitHub页面:https://github.com/jbj88817/GoogleMap-InfoWindow-android/blob/master/app/src/main/java/com/bjiang/map_ex/MainActivity.java

    如果你真的想用 ImageLoader 来做,你可以看看这篇文章:http://androidfreakers.blogspot.com/2013/08/display-custom-info-window-with.html (但比使用 Picasso 从 URL 加载要复杂)

    【讨论】:

    • 我尝试使用默认信息窗口,但仍然面临同样的问题。我将尝试在我之前使用 AsyncTask 加载图像的活动中使用 Picasso。也许它会解决问题。
    • 谢谢,我把所有图片加载器都改成了毕加索,Zygote 错误消失了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    相关资源
    最近更新 更多