1

Summary

How does the imageProxy parameter in this lambda expression within Google's MLKit Vision example code get defined?

Details

I understand the basic concepts of lamda expressions, such as those given in the w3schools examples, and more detailed examples given by the Oracle examples but I am struggling to understand how the quoted one from the MLKit is resolved for the following reasons as it seemingly differs from the other examples:

  1. There is no variable declaration associated with analysisUseCase.setAnalyzer, like with the two last examples from the w3schools link above. So I don't know how imageProxy would be defined elsewhere via a call to some variable as there is no variable to refer to.
  2. According to the javadoc comments on setAnalyzer, the two parameters for analysisUseCase.setAnalyzer should be setAnalyzer(@NonNull Executor executor, @NonNull Analyzer analyzer). Unless an Analyzer object is some kind of Consumer, I see no relation to the first example in w3schools. Furthermore, it is my understanding that this would imply the lamda expression should return such an Analyzer object, but there is no return statement.

Furthermore, Android Studio's tooltip for it shows that it resolves to androidx.camera.core.ImageProxy imageProxy. How does the linter know how to resolve this?

The underlying question as to why I want to know this is that I am modifying this sample code and want access to the imageProxy.getWidth() method elsewhere in my code. Without understanding the lamda expressions, I am not sure how to access this object and associated method.

halfer
  • 19,824
  • 17
  • 99
  • 186
topher217
  • 1,188
  • 12
  • 35
  • `imageProxy` is the name of the parameter that is passed in when calling the lambda function. The type is known because the methods receiving the lambda probably has a specific type enforced. When writing the lambda method `imageProxy` does not exist in the sense that is does not have a value, same with any other parameter of any other method, they are placeholders which will have values when actually executed. – luk2302 Sep 07 '20 at 07:09
  • @luk2302 thanks for the comment, but unfortunately that much was fairly clear to me. The method "receiving" the lambda expression would be setAnalyzer in this case correct? The setAnalyzer method enforces the 2nd parameter to be of type Analyzer, not ImageProxy. This, although just a tangential question, is also causing me confusion. I also understand that imageProxy won't have a value until runtime, but I was trying to track down what it would be at runtime so that I could access whatever was defining it somewhere else in the code. Inline debugging nor a path search helped find it. – topher217 Sep 07 '20 at 10:03

1 Answers1

1

analysisUseCase is of type ImageAnalysis and offers a method setAnalyzer that has a ImageAnalysis.Analyzer as a second argument.

That Analyzer is an interface with one method meaning a lambda expression can be used in its place. The only method defined is analyze(ImageProxy image), and that is what the lambda actually represents in this situation. As you can see the one argument to analyze is ImageProxy.

luk2302
  • 55,258
  • 23
  • 97
  • 137
  • Thanks for the detailed breakdown. I was following the same path, but your explanation helped clarify the relationships better than I had previously understood. So I understand how the linter resolves the type now, but can you expand your answer to clarify where the imageProxy object would be created such that I could gain access to its methods (e.g. `getwidth()`)? My first instinct would be to look for somewhere calling the `analyze()` method such that I could see the ImageProxy object it must be passing, but I cannot seem to find such a call in the project. Am I asking the wrong question? – topher217 Sep 07 '20 at 10:35