Open sockeqwe opened 10 years ago
Tried to get the path to the folder containing the project with:
private String getExecutionPath() throws UnsupportedEncodingException {
String path = AnnotatedAdapterProcessor.class.getProtectionDomain()
.getCodeSource()
.getLocation()
.getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");
return decodedPath;
}
private String getWorkingDir() {
Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
return s;
}
private String getExcecutionByClassLoader() {
ClassLoader loader = AnnotatedAdapterProcessor.class.getClassLoader();
URL url = loader.getResource(".");
return url.getFile();
}
private String getByEnv() {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null);
Iterable<? extends File> locations = fm.getLocation(StandardLocation.SOURCE_PATH);
if (locations.iterator().hasNext()) {
return locations.iterator().next().getAbsolutePath();
}
return null;
}
None of this method returns the desired result
You could pass an argument to the apt processor: By adding the following to the build.gradle:
apt {
arguments {
androidManifestFile variant.processResources.manifestFile
}
}
the manifest file location will be passed as argument to the processor, then you can retrieve the layouts like this:
final String androidManifestFile = processingEnv.getOptions().get("androidManifestFile");
int index = androidManifestFile.lastIndexOf("manifests");
File androidManifest = new File(androidManifestFile);
String variant = androidManifest.getParentFile().getName();
File layoutsDir = new File(androidManifestFile.substring(0,index),"res/"+variant+"/layout");
for (File file : layoutsDir.listFiles()) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,file.getAbsolutePath());
}
(error checking omitted)
Thanks, good idea! That looks really promising!
android {
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res']
}
}
}
I guess that the path to res folder can be passed directly as annotation processor option somehow ...
According to http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Manipulating-tasks you could get the resource dir by using
apt {
arguments {
androidManifestFile variant.processResources.resDir
}
}
But I don't know if it's valid in case multiple resource dirs are specified in the sourceSets
Awesome! Thanks! I will try that tomorrow!
But what if you want to use AnnotatedAdapter within a android library project? The layoutfiles will be somewhere in build/generated/intermediates/library-package-name/res/
But I guess to getting started we could say: Use the @Field
annotations for library projects because you have to specify them explicit because auto detecting ViewHolder classes by scanning xml layouts does not work for library projects.
For the normal app project we could use the auto ViewHolder detection mode by scanning xml files of the app projects res folder passed as Annotation Processor option like suggested by you:
apt {
arguments {
androidManifestFile variant.processResources.resDir
}
}
Do you see a better solution?
I though about that, apart from scanning recursively from the intermediates dir looking for res folders I can't think of anything else. If as layout they use android.R.layout.simple_list_item_2
, for example, it won't be in the intermediates at all, because it's part of the android framework and it's located in the android sdk dir..
I think the most common case will be with the layout xml in the project, anyway.
A better name for the apt argument would probably be androidResourceDir, I forgot to change it in the previous comment, so in gradle there will be
apt {
arguments {
androidResourceDir variant.processResources.resDir
}
}
and in the processor:
final String androidResourceDir = processingEnv.getOptions().get("androidResourceDir");
File layoutsDir = new File(androidResourceDir);
for (File file : layoutsDir.listFiles()) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,file.getAbsolutePath());
}
Somewhere in the android gradle plugin documentation site is described how to get the path for the resource folder, but at the end you have to pass this path to your annotation processor (annotation processor can have options).
andbrain notifications@github.com schrieb am Do., 24. Dez. 2015 um 17:07 Uhr:
how are you friends i need working sample for access to resource folder from the annotation processor his codes not work for me hope helps me so soon :D
— Reply to this email directly or view it on GitHub https://github.com/sockeqwe/AnnotatedAdapter/issues/4#issuecomment-167131473 .
what do you mean with "to my annotation processor?". This feature is not implemented yet in AnnotatedAdapter. Are you going to implement your own annotation processor?
andbrain notifications@github.com schrieb am Do., 24. Dez. 2015 um 17:12 Uhr:
THANK Hannes Dorfmann happy to see your replying please just tell how pass this path to your annotation processor :D
— Reply to this email directly or view it on GitHub https://github.com/sockeqwe/AnnotatedAdapter/issues/4#issuecomment-167131934 .
You have to override getSupportedOptions()
in your annotation processor. Like this: https://github.com/sockeqwe/fragmentargs/blob/master/processor/src/main/java/com/hannesdorfmann/fragmentargs/processor/ArgProcessor.java#L107
Then with android apt plugin you can do something like this:
apt {
arguments {
resPath "path/to/res/folder"
}
}
Automatically detect fields from the corresponding xml layout files by checking for views with an id. So you don't have to specify fields for the view holder by hand with
@Field
However, that's not an easy task:
res
folder itself is configureable through gradle configurationHowever it would be awesome to have such a feature!