【问题标题】:java.lang.NullPointerException: Attempt to invoke interface method on a null object reference [duplicate]java.lang.NullPointerException:尝试在空对象引用上调用接口方法[重复]
【发布时间】:2019-01-26 16:27:21
【问题描述】:

以下代码引发 NullPointerException,我不知道为什么。如果有人能指出我的错误,那将不胜感激。

来自 MainActivity 的代码,错误在第 4 行:

private void init(){
    this.createClassifier();
    this.takePhoto();
}

private void createClassifier(){
    try {
        classifier = ImageClassifierFactory.create(
                getAssets(),
                Constants.GRAPH_FILE_PATH,
                Constants.LABELS_FILE_PATH,
                Constants.IMAGE_SIZE,
                Constants.GRAPH_INPUT_NAME,
                Constants.GRAPH_OUTPUT_NAME);
    }catch (IOException e) {
        Log.e("MainActivity", e.getMessage());
    }


}
private Classifier classifier; 
...

private final void classifyAndShowResult(final Bitmap croppedBitmap){
    runInBackground((new Runnable(){
        public final void run(){
            Result result = classifier.recognizeImage(croppedBitmap);
            showResult(result);
        }
    }));

}

有不同的方法调用 init(),所以我不知道为什么分类器没有被初始化。

结果类:

public class Result {
private String result;
private float confidence;

public Result(String result, float confidence) {
    this.result = result;
    this.confidence = confidence;
}

public String getResult() {
    return result;
}

public void setResult(String result) {
    this.result = result;
}

public float getConfidence() {
    return confidence;
}

public void setConfidence(float confidence) {
    this.confidence = confidence;
}
}

分类器接口:

public interface Classifier {
Result recognizeImage(Bitmap bitmap);

和发起的recognizeImage:

public Result recognizeImage(Bitmap bitmap){
    preprocessImageToNormalizedFloats(bitmap);
    classifyImageToOutputs();
    PriorityQueue outputQueue = new PriorityQueue(getResults());
    Object queue = outputQueue.poll();
    return (Result)queue;
}

错误代码是:java.lang.NullPointerException: Attempt to invoke interface method 'classifier.Result classifier.Classifier.recognizeImage(android.graphics.Bitmap)' on an null object reference

ImageClassifier 构造函数:

 public ImageClassifier(String inputName, String outputName, long imageSize, List labels, int[] imageBitmapPixels, float[] imageNormalizedPixels, float[] results, TensorFlowInferenceInterface tensorFlowInference) {
    this.inputName = inputName;
    this.outputName = outputName;
    this.imageSize = imageSize;
    this.labels = labels;
    this.imageBitmapPixels = imageBitmapPixels;
    this.imageNormalizedPixels = imageNormalizedPixels;
    this.results = results;
    this.tensorFlowInference = tensorFlowInference;
}

ImageClassifierFactory 类:

public class ImageClassifierFactory {

public final static Classifier create(AssetManager assetManager, String graphFilePath, String labelsFilePath, int imageSize, String inputName, String outputName) throws IOException {

    List labels = getLabels(assetManager, labelsFilePath);
    ImageClassifier  im = new ImageClassifier(inputName, outputName, (long)imageSize, labels, new int[imageSize * imageSize], new float[imageSize * imageSize * COLOR_CHANNELS], new float[labels.size()], new TensorFlowInferenceInterface(assetManager, graphFilePath));
    return im;

}

}

【问题讨论】:

  • 听起来classifiernull。你在哪里定义它?
  • 我将它定义为MainActivity顶部的“私有分类器分类器”。我已经看过这个问题,但我似乎不知道如何解决这个问题。
  • 那你在哪里初始化 classifierNullPointerException 总是意味着同样的事情。您正在尝试使用尚未初始化的变量(因此是 null)。

标签: java android interface


【解决方案1】:

您不能创建接口 Classifier 的分类器实例。 您需要将 Classifier 更改为 A 类并创建该类的分类器实例或创建另一个实现 Classifier 接口的类的实例

【讨论】:

  • 识别图像方法在实现分类器接口的 ImageClassifier 类中启动。你是这个意思吗?我不确定如何在我们的方法中创建此类的实例。我是初学者,如果我没有正确理解你,我很抱歉
  • 由于在 ImageClassifier 类中实现了识别图像方法,现在您需要创建该类的实例并作为属性分类和显示结果类
  • 你的意思是我必须在classifyAndShowResult所在的类中创建一个ImageClassifierInstance的实例吗?
  • 是的。你需要在classifyAndShowResult存在的类中创建一个ImageClassifierInstance的实例
  • 你能看看更新的代码吗?因为我们在 ImageClassifierFactory 中创建了一个对象,所以我认为我们必须以某种方式合并该对象而不是 ImageClassifier,但我不确定如何/是否。
【解决方案2】:

声明classifyAndShowResult-Method 的类必须在其属性中包含classifier。在您调用该方法时,该变量为null。要对此进行调试,您应该在“调试”模式下启动您的应用程序(假设您在 Eclipse 中编程),然后读取 NullPointerException 的堆栈以找出未启动 classifier 的原因。

@编辑: 在看到为分类器截取的代码后,您需要执行以下操作:

private Classifier classifier = new ImageClassifier();

...假设classifier在初始化时不需要参数。

【讨论】:

  • 我有一个 ImageClassifier 类的构造函数,因为我们在另一个类 (ImageClassifierFactory) 中调用它。我会将这些添加到原始帖子中,但我不确定 ImageClassfierFactory 是否与此相关联。是不是我必须以某种方式将其纳入声明中?
  • 视情况而定。这是运行时的问题。如果在调用classifyAndShowResult 之前设置了属性classifier,那么您的代码此时不应抛出NPE,除非它是用null 初始化的。但确实如此。如果我是你,我会在那个特定的代码点设置一个断点,然后运行它。然后看一下'variables'-View of eclipse,你自己看看,那个(可能)classifier还没有被初始化。
猜你喜欢
  • 2016-04-23
  • 2018-02-05
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 2015-03-23
  • 1970-01-01
  • 2021-06-12
  • 2016-07-30
相关资源
最近更新 更多