Resources from jar available from source code but not in xml - android

I've compiled SettingsLib and copied jar to my project: frameworks/base/packages/SettingsLib/SettingsLib/android_common/javac/SettingsLib.jar
Jar contains this drawable that I would like to use. It's accessible in Java code:
int id = com.android.settingslib.R.drawable.avatar_selector;
but when I try to use it in xml files:
android:drawable="#drawable/avatar_selector"
it fails due to:
AAPT: error: resource drawable/avatar_selector not found.

Ok, I've figured it out myself. The procedure is ugly so no wonder there is no info about it from Google developers, maybe they were ashamed of the process and preferred to keep this for themselves :D If there is better way to do that then please let me know.
First of all if you just build Android with "make" you will not have aar files in out directory, just the jars (maybe with some small exceptions). What you need to do is to "make " e.g. "make SettingsLib" (weird but this is how it currently is), this will additionally generate aar here:
out/soong/.intermediates/frameworks/base/packages/SettingsLib/SettingsLib/android_common/SettingsLib.aar
but it's not the end of the story ... If you unzip and compare SettingsLib.jar with SettingsLib.aar you will notice that jar contains:
META-INF, androidx, com
while aar contains:
META-INF, AndroidManifest.xml, classes.jar, R.txt
but ... if you open "magic" aar that Google put into source code e.g. prebuilts/sdk/current/aaos-libs/car-apps-common.aar you will notice that it additionally contains res directory:
META-INF, res, AndroidManifest.xml, classes.jar, R.txt
so what you need to do is to unzip generated aar (in this case SettingsLib.aar), then copy paste resources (in this case frameworks/base/packages/SettingsLib/res), zip the files once again, change extension to .aar and finally resources will be available also from the xml files.
You might also encounter some problems with duplicated strings or binary resources conflicting with the normal ones and you might need to clean project when rebuilding but other than that it should work.

Related

aar vs "plain module" advantages

if I have a project with many library projects linked, could I improve build performances by packaging each of them in an AAR and including it in the main project ? Or this will not make any difference since that when the compiler need to assemble the apk it need to package everything together anyway?
Thanks to any one who will give me some clarifcation about performance differences between the 2 approach
I don't think you will save any build time by wrapping an existing .jar file into a .aar file and using that instead of the original .jar file.
As this SO post notes, .aar files are basically just zip files which may contain a jar file and some android resources.
Also, because .aar files are not precompiled into Dalvik byte code, the build process for your apk file must still carry out that step at least once. So, you won't save dexing time just by wrapping the .jar file into a .aar file either.
If you build a typical Android Studio project (with some Android library dependencies specified in the gradle build file) you can see the directory underneath app/build/intermediates/exploded-aar where these files have been unzipped. That work must still be done by your build machine even though you are using a .aar file.
Finally, as you pointed out, the .apk packaging work must still be done at the end of the build.
I believe the Library projects (which you are using) is the best way to go because of two reasons:
The library project gives the direct access to the code base of the libraries which can be compiled and packaged together with the main app code
In case, multiple .aar files are referenced within the project, then during the apk creation the unpacking, merging of resources and Manifest file will increase the build time.

Install resource file into root of apk

When you use a jar as a dependency, any files in the jar root are put into the generated apk's root. Meanwhile, if I just have my android project, and I want to put files in the root, I can't! I have to put files in res/assets or res/raw, which won't do the trick for me.
I'm using a library internal to the company, and it expects a filename for something in the top-level of the produced artifact
With old android projects (the ones that use ant, etc), put your resource files in /resources (not /res) to ensure that they aren't touched by aapt and are put in the root.
For new android projects (ones using gradle), put these resources in src/main/resources

Excluding files from compilation

I have a number of files in a project that I don't want to include in the compiled apk.
For source files, right-click -> Build Path -> Exclude does the trick.
How about for excluding other files, for example certain ones in the assets folder? If my understanding is correct, all of these are included in the apk by default.
Also, if I create a custom folder in my project structure (e.g. inside the assets onee) it will show in the package explorer. Would its contents be added to the apk?
Apparently, folders named _pre_production are not added to the APK.
I cannot take credit for this. Here is where I found the answer:
Ignoring files from Android APK
I'm duplicating the answer here in case someone comes by.

Use already developed android project [with its resources(xml, images, layout)] into another project directly as .xyz file

I have read lots of questions on this site and come to the decision that if you wish to use your already developed code with its resources in android then you have to use it as a library.
But from the Building Android applications with Gradle tutorial I read something like...
Gradle supports a format called Android ARchive (AAR) . An AAR is similar to a JAR file, but it can contain resources as well as compiled bytecode. This allows that an AAR file is included similar to a JAR file**.
Does it means that we can use .aar file as an .jar file but with facility of using resources also?
Then I have tried to crate .aar file with the help of Android Studio, but .aar file doesn't contain layout XMLs or images -- it contains some layout and resources but it doesn't contain projects other resources file.
At last I am having the only same, annoying, stupid question: Can we use whole project with its resources with only one file like .jar or .aar or any other file format?
RajaReddy is quite mistaken. The JAR contains only code; you cannot access resources that way.
Google distributes their own "Google Play Services Library" as an Android library project, containing the binary code in a JAR file in the lib directory, the resources in the res directory, and an UnusedStub class in the src directory. If a better approach were viable yet I think they'd be using it.
UPDATE: While Android Studio is still in beta, it includes (buggy) support for AAR files. Seems this will eventually be the way to go.
Library projects bin folder contains jar file, copy that jar file in your main Application ( project ) libs folder we can get all the resource folders like this.
Follow these steps !
1) make your library project a normal project by deselecting IsLibrary flag.
2) Execute your project as Android Application. (It will not show any error)
3) you'll find a .jar file in bin folder..
4) Copy .jar in libs folder of your main application.
this will works fine with all the resources.
I was looking for the same thing for years. Combining byte code of java and resources (xml and other files) into one package. Currently I don't think its possible because even google has to include add resources separately in google play services lib available in the SDK .
What you can do best is generate a .aar or .jar file and add a folder of missing resource files.

Is library file present in .apk file?

Actually I want to know that if in my application's libs folder, any library file(e.g .jar file) is present, then after installing(running) that application, will library file present in .apk file?
According to my understanding, library FILE should present in generated .apk file. If I am wrong then please correct me.
If my question is below standard, then extremely sorry for that. Any help will be well appreciated
With recent versions of the Android tools, .jar files in the libs folder are automatically included in the build. (See Dealing with dependencies in Android projects.) So, yes, the library is included in the compiled bytecode (not as a separate file).
If you use ProGuard in a release build, then it will attempt to strip out any code which is not actually used. So, it may be that some parts of the library are included in the final .apk, and some parts are removed.
the answer is yes. The apk is just a zipped version of your compiled project. If you open it with winrar for example, youll see that everithing is in there ;)
You can try it and see yourself but you can not directly see the .jar file under libs folder in the apk generated. Library class files are all together are compiled into a single .dex file. If you decompile that dex file, you can reach the java codes.

Categories

Resources