Glide Version: 4.0.0
Integration libraries: okhttp3-4.0.0
I'm getting the following error in my application indicating to me that I'm not running my annotation processor, when I am:
08-12 11:44:45.559 1053-1374/com.google.android.googlequicksearchbox:search W/Glide: Failed to find GeneratedAppGlideModule. You should include an annotationProcessor compile dependency on com.github.bumptech.glide:glide:compiler in your application and a @GlideModule annotated AppGlideModule implementation or LibraryGlideModules will be silently ignored
Explanation: This error is happening, because Glide is requiring that I run the annotation processor on my actual android application module rather than on a library module. The only way to get good performance out of annotation processors is to avoid running them altogether through compile-avoidance and caching, otherwise if the code the annotation processor is attached to is compiled, the annotation processors have to run.
I created a small library module that was at the very end of the module dependency chain and used it to configure glide, and run the annotation processor. Instead, when I use Glide in this manner it gives me the above error, and forces me to move my annotation processor to my actual application. As soon as I do that, it no longer complains and works.
Request / Expectations / Bug: Glide's Annotation Processor should be able to be run on a smaller library module so that Glide's Annotation Processor isn't forced to be run on every single incremental Android build for the application. An approach I'd be even happier with it, is allow configuration 100% without an annotation processor, so that the annotation processor isn't required at all.
Question / comments: Why did Glide go the annotation processor direction? It seems like Glide is only using the annotation processor to generate a GlideApp that is properly configured, and to add custom configuration functions.
For the functionality the annotations provide, see http://bumptech.github.io/glide/doc/generatedapi.html. There aren't many other alternatives for initialization, the previous one we tried (metadata in AndroidManifest.xml) is broken on some devices or for apps with sufficiently complex manifests.
Glide's annotation processor will run on libraries. The only requirements are that you have exactly one AppGlideModule and that the library containing the AppGlideModule depends on any LibraryGlideModules you want to include. We actually use this approach in Photos.
If you have some data that quantifies the amount of time Glide's annotation processor adds to builds, feel free to open an issue and we can see what we can do to minimize it.
@sjudd I have exactly one AppGlideModule. I'm still seeing the 'annotation processor has not been run' message intermittently, when everything has been setup properly to use the annotation processor. Now I'm not seeing the message, but an hour and a half ago I was. I haven't noticed any issues with using Glide though, but right now I'm only using it in a very small location in my app.
There aren't many other alternatives for initialization, the previous one we tried (metadata in AndroidManifest.xml) is broken on some devices or for apps with sufficiently complex manifests.
It seems like with your previous manifest meta-data approach, and now your annotation processor approach, you really want the ability to just include a dependency, and have everything just magically work and stitch itself together. I think that can potentially work for the default case, but you can see from my ticket here ( https://github.com/bumptech/glide/issues/2238 ), I'm having to disable that behavior and manually stitch things together myself in a relatively unintuitive way for something as minor as adding a header to my image requests.
My opinion is that the builder API is less magical and more intuitive.
Glide glide = new Glide.Builder()
.withLibrary(new OkHttpLibraryGlideModule(customHttpClient))
.build();
Glide.setSingletonInstance(glide);
I also find it fairly difficult to get custom information into my AppGlideModule as I don't have control over the constructor. For instance, my company uses an API manager, and our testing and production environments use different API keys. I need to somehow pass the current server information to the AppGlideModule, so I can add the api key header to all of the requests. I'm forced to use 1 of 2 options, none of which feel right:
AppGlideModule is constructed, and set it in a static field somewhere, where the AppGlideModule can read it. (Which becomes even more difficult when you are trying to move your AppGlideModule into a library so that the annotation processor doesn't have to run each build)getSystemService on the Activity or Application.Builder APIs are certainly easier to use, but they're also very easy to get wrong. It's difficult to guarantee that your call happens only when the library is used and before any request is made. Failing to do so can lead to randomly broken loading, or worse, security issues if the wrong library is used.
A common answer to injecting information would be to use a dependency injection framework.
If you don't want to go that far, you could also just define a static method that both your module and your API manager can all to get the current server info. That may be more difficult depending on your library set up though.
A common answer to injecting information would be to use a dependency injection framework.
This is the approach I have working currently. I'm exposing the dependency graph to the glide module through getSystemService.
This issue has been automatically marked as stale because it has not had activity in the last seven days. It will be closed if no further activity occurs within the next seven days. Thank you for your contributions.
Most helpful comment
It seems like with your previous manifest meta-data approach, and now your annotation processor approach, you really want the ability to just include a dependency, and have everything just magically work and stitch itself together. I think that can potentially work for the default case, but you can see from my ticket here ( https://github.com/bumptech/glide/issues/2238 ), I'm having to disable that behavior and manually stitch things together myself in a relatively unintuitive way for something as minor as adding a header to my image requests.
My opinion is that the builder API is less magical and more intuitive.
I also find it fairly difficult to get custom information into my
AppGlideModuleas I don't have control over the constructor. For instance, my company uses an API manager, and our testing and production environments use different API keys. I need to somehow pass the current server information to theAppGlideModule, so I can add the api key header to all of the requests. I'm forced to use 1 of 2 options, none of which feel right:AppGlideModuleis constructed, and set it in a static field somewhere, where theAppGlideModulecan read it. (Which becomes even more difficult when you are trying to move yourAppGlideModuleinto a library so that the annotation processor doesn't have to run each build)getSystemServiceon theActivityorApplication.