I've been trying to fix this problem for an entire day, and it's probably just something ridiculous. I'm running Android Studio 0.2.5. I needed a library to work on my application (GrepCode internal stuff), so I went and downloaded the jar file and the jar files it depends on. I followed instructions from other SO answers on how to include these dependencies into my project and now I'm getting an error.
1) I first added the jars to the 'libs' folder that I created in the Module
2) I right clicked and hit Add to Library..., named the Library, tried adding it at different levels and still get this error.
3) I went into the Modules section of the settings and made sure that library was selected under the Dependencies tab.
4) I run gradlew clean in the Project directory.
Now at this point, if I don't do step 5 here, I simply get an error saying the packages I'm trying to import don't exist, even though the IDE doesn't SHOW an error when typing out the import statements or the classes from the libraries. Because of this, I tried step 5. According to all the guides, what I did up to this point should have worked.
5) In my build.gradle, the dependencies did not show up, so I typed them out and now this is what my dependency section looks like. If I do not type these out, I just get an error that says the packages don't exist when I try to import them.
dependencies {
compile 'com.android.support:support-v4:13.0.0'
compile files('libs/openjdk-6-b14.jar')
compile files('libs/junit-3.8.1.jar')
compile files('libs/logkit-1.0.1.jar')
compile files('libs/servlet-api-2.3.jar')
compile files('libs/httpcore-4.0.1.jar')
compile files('libs/commons-codec-1.3.jar')
compile files('libs/commons-logging.jar')
compile files('libs/httpclient-4.0.1.jar')
compile files('libs/json-20080701.jar')
compile files('libs/opengl-api-gl1.1-android-2.1_r1.jar')
compile files('libs/xpp3-1.1.4c.jar')
compile files('libs/android-4.2.2_r1.jar')
}
After this I get an error in the message box saying "Gradle: Execution failed for task ':SendPicTest:dexDebug'."
And in the idea.log I find this error: "java.lang.OutOfMemoryError: GC overhead limit exceeded"
So, I believe Step 5 is unnecessary, but I'm not sure. I've tried many different ways of importing these libraries and NOTHING has worked...I'm completed lost...anybody have any ideas? Thanks!
EDIT
After looking at your dependencies list, it seems obvious that the problem is there. I suggest you to try to:
1) understand why you choose to include each of those libs.
2) understand the android architecture and build process. (maybe read this)
Here are a few remarks:
openjdk-6-b14.jar MUST be removed. You are developing an Android app and so it will run against the Android SDK. The Android SDK already define most of the classes of the openjdk (so you will have conflicts when dexing this jar). Additionally lot of classes in this jar are simply not dexable (like javax.swing.*) because they use unsupported features and don't make sence on Android.
android-4.2.2_r1.jar is a stub jar (look at the code: all methods throw an exception). This artifact is only usable the build your android code with a standard javac compiler (and so producing *.class file). After that, all your *.class will be dexed (i.e. transformed into *.dex files) by android compiler. At runtime, the real android-api implementation will be used (instead of this artifact).
servlet-api : it's very uncommon to need this in an android-app. It only define an API (without implementation). The implementation is usually provided by the application server (tomcat, jboss,...) in standard J2EE developement. Android-sdk don't provide an implementation for this API.
junit : usually a dependency with scope test.
httpcore (and probably also httpclient) : a common mistake on android. An old implementation of this library is included in the android-sdk. If you keep it, you will have a top-level exception while building your app (this exception means that you try to override a class from the android-sdk : this is not possible)
opengl-api-gl1.1-android-2.1_r1.jar : I don't know exactly what it contains, but I guess the same remark as what I wrote about android-4.2.2_r1.jar applies here.
END EDIT
So, I believe Step 5 is unnecessary
No step 5 is necessary ! The build.gradle is where dependencies are defined... so if AndroidStudio don't update this file for you : do it by hand.
After that, you may need to reimport the project from gradle files (find the reimport button on top of the gradle view on the right edge of the window)
Regarding the error in the log file:
You can increase AndroidStudio memory settings from this file:
<ANDROID_STUDIO_INSTALL_DIR>/bin/studio.exe.vmoptions
or
<ANDROID_STUDIO_INSTALL_DIR>/bin/studio64.exe.vmoptions
if you run 64 bits version.
I suggest you to try to change the settings to avoid the "java.lang.OutOfMemoryError: GC overhead limit exceeded"
This error means that GC is running very long (98% of the time) and less than 2% of the heap is released. So you can try to increase the heap (and restart AndroidStudio):
-Xmx1024m
Another option, is to disable this check by adding this line in the *.vmoptions file:
-XX:-UseGCOverheadLimit
(note that since it is not a standard JVM args: it may not be supported by your JVM) Anyway I don't recommend this option, since the GC will run for a while with very poor results and your IDE will be very very unresponsive.
I also suggest you to read this regarding usage of AndroidStudio today.
Related
I have a MyLocationService library, which has dependency from huawei_location_service.Inside I have HMSLocationService class which is the only one using huawei_location_service classes and I use relfection to access that class. Meaning is, if we run app on Huawei and if there is dependency from huawei_location_service, I will get location, otherwise will not. And application should run perfectly on non-hauwei devices without dependency from huawei_location_service.
So when I build MyLocationService.aar I removed huawei_location_service dependency from it's pom file. After that I created a new application and added dependency from MyLocationService.aar. When I check dependencies with command gradlew app:dependencies I don't see any dependency from huawei, but when I create an apk and analyze it, in classes.dex there are classes from huawei_location_service.
Question: How it is possible? And is there any other way to achieve what I want?
P.S. I analyzed also MyLocationService.aar, didn't find any huawei dependency. Is there another way to check dependencies of *.aar files instead of pom or analyzing tool of android studio?
So if someone will be mistaken as me, this answer will help.
The repositories and classes I saw in classes.dex were not coming from hms libraries. As I have imports in my custom classes, that imports' texts were the reason I was seeing huawei folder in classes.dex. Also take attention on the size, and you can see that they are kind of 20 bytes.
So I removed the imports, generate my library again, created apk and analyzed it and woala, no huawei folder is visible.
P.S. *.aars doesn't contain any library if you not put transitive=true. And you need to add dependencies required by your lib in your own applicaiton.
P.S.S. If you have locally or globally publishing your library, maven(Gradle uses maven) creates metadata, so called POM file, as a helper to identify all dependencies that the library needs.
I'm trying to build an app bundle but I'm getting the following error:
File 'root/lib/x86_64-MacOSX-gpp/jni/libjunixsocket-native-2.0.4.jnilib' uses reserved file or directory name 'lib'.
For what I've seen from similar questions, this issue is normally solved juggling dependencies or files in the project structure, but in this case it seems to point to a native library involved in app architecture if i'm not mistaken. Any ideas how to solve this?
It looks like you are adding a dependency as a jar instead of an aar.
The aar contains the information of what files should be considered as Android resources, native libraries, etc. in the app. A jar is just a plain list of files without Android concept. Because the jar you're depending on contains a directory lib, the files would normally end up being considered as native libraries, but because the files come from a jar instead of an aar, the build system warns that it's unlikely to be a native library and may have unintended consequences at runtime.
Try to package that library as an .aar instead of a .jar. See this documentation: https://developer.android.com/studio/projects/android-library
Edit:
Note that this file could not be loaded by the Android platform if it was included as is in the APK, so even though the previous build systems would allow you to put anything in an APK, the Android App Bundle is more restrictive to ensure that you don't accidentally put unnecessary files which would increase unnecessarily the size of your app.
Ok it is working now! Steps I used to found the problem (thanks for pointing me in the right direction #Pierre)
Run a gradle build --scan from your terminal or go to the Gradle tab in Android Studio, select :app, help , androidDependencies to see your dependency graph.
Search the dependency graph for the library name related to the problem ( in my case I searched for socket, there was no match for libjunixsocket for example).
Going upwards on the dependency tree I realized it was caused by the 'io.voucherify.android.client:voucherify-android-sdk:2.1.0' dependency.
I just added #aar at the end of the dependency implementation, and I managed to build the app bundle.
implementation 'io.voucherify.android.client:voucherify-android-sdk:2.1.0#aar'
I've recently ran into this problem, and would like to know, if possible, whether there's a solution for it.
Basically in the project I'm currently working, there used to be some legacy class files that were deleted in a past commit, but sometimes I need to look them up for quick reference, so I just reverted them back to my local changelist and set them as unversioned.
Now, the problem is that due to the legacy nature of these files, some of them don't compile anymore, but the gradle build attempts to compile them although they're unversioned.
So, my question here is: Is there a way to make gradle ignore unversioned files, just stop contemplating them for the build?
No, there is no such way. Gradle cannot exclude files from build based on their version control status. If you only need to use those classes for reference, move them to a directory outside of your project root directory.
I was wondering what is the recommended way of including library projects in an Android Studios gradle like this:
First way:
compile 'de.greenrobot:greendao:2.1.0'
Second way:
compile files('libs/greendao-2.0.0.jar')
and what are the pros and cons.
In the first case gradle is completely handling the process of dependency management, i.e. downloading the jar and including it in your project.
In the second case you have to manually download the jar and include it in the libs folder.
The simpler and preferred way is the first.
First way: compile 'de.greenrobot:greendao:2.1.0'
PRO:
Easy, quick to update
CON:
Internet connection required when updating your gradle file
Second way: compile files('libs/greendao-2.0.0.jar')
PRO:
You can make changes to the library and those won't be overwritten.
Like Qian Sijianhao said, it's quicker to build.
CON:
More work to set up, update
In most cases I think you want to go with the first way.
Trust me, the second way will save lots of your building time.
By the way , time is money.
In the first way, i.e:
compile 'de.greenrobot:greendao:2.1.0'
compile 'com.library.sample:library:x.x.x'
Gradle will finding these dependencies, and making them available in your build. If your dependencies have a dependencies, gradle will also finding them and include it for the project. So you don't need to manually add all the dependencies.
Quoting from Gradle documentation:
7.1. What is dependency management?
Very roughly, dependency management is made up of two pieces. Firstly,
Gradle needs to know about the things that your project needs to build
or run, in order to find them. We call these incoming files the
dependencies of the project. Secondly, Gradle needs to build and
upload the things that your project produces. We call these outgoing
files the publications of the project. Let's look at these two pieces
in more detail:
Most projects are not completely self-contained. They need files built
by other projects in order to be compiled or tested and so on. For
example, in order to use Hibernate in my project, I need to include
some Hibernate jars in the classpath when I compile my source. To run
my tests, I might also need to include some additional jars in the
test classpath, such as a particular JDBC driver or the Ehcache jars.
These incoming files form the dependencies of the project. Gradle
allows you to tell it what the dependencies of your project are, so
that it can take care of finding these dependencies, and making them
available in your build. The dependencies might need to be downloaded
from a remote Maven or Ivy repository, or located in a local
directory, or may need to be built by another project in the same
multi-project build. We call this process dependency resolution.
Note that this feature provides a major advantage over Ant. With Ant,
you only have the ability to specify absolute or relative paths to
specific jars to load. With Gradle, you simply declare the “names” of
your dependencies, and other layers determine where to get those
dependencies from. You can get similar behavior from Ant by adding
Apache Ivy, but Gradle does it better.
Often, the dependencies of a project will themselves have
dependencies. For example, Hibernate core requires several other
libraries to be present on the classpath with it runs. So, when Gradle
runs the tests for your project, it also needs to find these
dependencies and make them available. We call these transitive
dependencies.
Gradle will store the downloaded library to your USER_HOME/.gradle. In Linux, it will store it in /home/user/.gradle/caches/modules-2/. in Mac it will store it in ~/.gradle/caches/modules-2/.
By the way, if you have used the library, you can set Android Studio to use a local cache of the library.
In the second way, you need to manually add the library for your project. And you also need to include all the remaining dependencies of the library. This is so error prone.
I built AOSP 5.1.0_r3 and imported into IntelliJ. And followed these steps.
But When I open for example PackageManagerService.java code its not able to compile and its referencing external/robolectric/lib/main/android.jar/android/os/Process. For example SHELL_UID is missing:
private static final int SHELL_UID = Process.SHELL_UID;
If I look in standard android.jar the SHELL_UID it's there.
There are many more cases like this. What could be wrong here?
Screen1:
Screen2:
-----> UPDATE 2 FIXED ISSUES:
Added excluded-paths also found out that I had to delete the dependencies in the Project structure:
In PackageManagerService.java it still cant resolve symbol:
-----> UPDATE 2 OPEN ISSUES:
And in this Manifest (and others) it cant resolve several symbols (related to Android):
This is not a common problem I'm aware of, so I'm not entirely certain why you are seeing this error specifically. Regardless, to avoid the IDE getting confused, you could add external/roboelectric to a custom excluded-paths file so Idegen will ignore it in the generated IDE classpath.
If you don't already have one of these files, it goes in the top-level directory of your AOSP tree, and contains directories to exclude during generation. You can see the built-in exclude file for example syntax.
Idegen is supposed to exclude all JAR files, but it may only do that for files in out/ and prebuilts/.