尝试在空对象引用上调用虚拟方法 'int org.gdal.ogr.Layer.CreateField(org.gdal.ogr.FieldDefn)'

Attempt to invoke virtual method 'int org.gdal.ogr.Layer.CreateField(org.gdal.ogr.FieldDefn)' on a null object reference

在Android中,我使用GDAL将SQLite数据导出为Shapefile格式。但我得到这个例外:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int org.gdal.ogr.Layer.CreateField(org.gdal.ogr.FieldDefn)' on a null object reference

我的代码:

    static {
        System.loadLibrary("gdaljni");
        System.loadLibrary("ogrjni");
        System.loadLibrary("osrjni");
    }

    public void WriteToShapeFile(Uri uri) throws FileNotFoundException {
        ogr.RegisterAll();
        ArrayList<ReportModel> cursor = databaseHelper.getReports();
        ArrayList<String> key_args = new ArrayList<>();
        key_args.add("id");
        key_args.add("name");
        key_args.add("geometry");
        key_args.add("type");
        Driver driver = ogr.GetDriverByName("ESRI Shapefile");
        final String fileName = "citizen_problems";
        //Saving file in external storage
        File sdCard = Environment.getExternalStorageDirectory();
        File directory = new File(sdCard.getAbsolutePath() + "/citizen_problems/" + fileName);
        if (!directory.isDirectory()) {
            directory.mkdirs();
        }
        //file path
        File file = new File(directory, fileName);
        DataSource data_source = driver.CreateDataSource(file.getAbsolutePath());
        SpatialReference srs = new SpatialReference("");
        org.gdal.ogr.Layer layer_;
        layer_ = data_source.CreateLayer(fileName, srs, ogr.wkbPoint);
        for (String item : key_args) {
            FieldDefn field_name = new FieldDefn(item, ogr.OFTString);
            layer_.CreateField(field_name);
        }
        for (ReportModel row : cursor) {
            Feature feature = new Feature(layer_.GetLayerDefn());
            feature.SetField("id", row.getId());
            feature.SetField("name", row.getName());
            feature.SetField("type", row.getType());
            Geometry geom = null;
            try {
                String geo = row.getGeometry();
                if (geo != null) {
                    geom = ogr.CreateGeometryFromWkt(geo);
                    feature.SetGeometry(geom);
                }
            } catch (Exception e) {
            }
            layer_.CreateFeature(feature); 
        }
    }

CreateLayer() 方法returns null,我不明白为什么。

layer_ = data_source.CreateLayer(fileName, srs, ogr.wkbPoint);

我不知道这个问题。请帮助我

我将 mkdir() 更改为 mkdirs(),问题就解决了:)

最终代码为:

 public void WriteToShapeFile(Uri uri) {
    ogr.RegisterAll();
    ArrayList<ReportModel> data = databaseHelper.getReports();
    Driver driver = ogr.GetDriverByName("ESRI Shapefile");
    String fileName = "citizen_problems.shp";
    File directory = new File(getFilesDir(),  "/shapefiles/"+ fileName);
    if (!directory.isDirectory()) {
        directory.mkdirs();
    }
    File file = new File(directory, fileName);

    DataSource dataSource = driver.CreateDataSource(file.getAbsolutePath(),null);
    SpatialReference srs = new SpatialReference("");
    Layer layer = dataSource.CreateLayer(fileName, srs, ogr.wkbPoint,null);
    Layer l = dataSource.CreateLayer(fileName);
    Layer ll = dataSource.CreateLayer(fileName,srs,1,null);

    ArrayList<String> key_args = new ArrayList<>();
    key_args.add("id");
    key_args.add("name");
    key_args.add("type");
    key_args.add("geometry");

    for (String item : key_args) {
        layer.CreateField(new FieldDefn(item, ogr.OFTString));
    }

    for (ReportModel row : data) {
        Feature feature = new Feature(layer.GetLayerDefn());
        feature.SetField("id", row.getId());
        feature.SetField("name", row.getName());
        feature.SetField("type", row.getType());
        String geom = row.getGeometry();
        if (geom != null) {
            feature.SetGeometry(ogr.CreateGeometryFromWkt(geom));
        }
        layer.CreateFeature(feature);
        feature = null;
    }
    Utils.zipFileAtPath(getFilesDir() + "/shapefiles/"  + fileName, uri, this);
}