Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to put my libraries in front of android.jar by editing build.gradle in Android-Studio

First Here's my Java Build Path in Eclipse: enter image description here

These four jars 'common.jar,core.jar, framework.jar,layout.jar' are packaged from Android source code, which contains some classes that can't be publicly used by developer.They needn't to be exported because they are for cheat compiler. In Eclipse everything is OK.

Now I'm trying to import my project to Android-Studio with gradle.I've add the jars to dependencies,However I can't change the compile order of my jars and android jar. I can't put these jars in front of android jar.I'm not familiar with gradle, now the compiler can't find classes in these jars. Any help will be appreciated! Here's my build.gradle:

apply plugin: 'android'    
dependencies {

    compile files('jars/common.jar')
    compile files('jars/core.jar')
    compile files('jars/framework.jar')
    compile files('jars/layout.jar')
    compile fileTree(dir: 'libs', include: '*.jar')
    compile files('jars/animation_nineoldandroids_src.jar')
    compile files('jars/json_simple_src.jar')
    compile files('jars/jsoup-1.7.2-sources.jar')
}

android {

    compileSdkVersion 17
    buildToolsVersion "21.1.1"
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        // Move the tests to tests/java, tests/res, etc...
        instrumentTest.setRoot('tests')

        // Move the build types to build-types/<type>
        // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
        // This moves them out of them default location under src/<type>/... which would
        // conflict with src/ being used by the main source set.
        // Adding new build types or product flavors should be accompanied
        // by a similar customization.
        debug.setRoot('build-types/debug')
        release.setRoot('build-types/release')
    }
}
like image 425
WZY Avatar asked Dec 12 '14 10:12

WZY


People also ask

Where should I add library in Android Studio?

To use your Android library's code in another app module, proceed as follows: Navigate to File > Project Structure > Dependencies. In the Declared Dependencies tab, click and select Library Dependency in the dropdown. In the Add Library Dependency dialog, use the search box to find the library to add.

Where does Gradle build Put the jar?

The Jar is created under the $project/build/libs/ folder.

What is the use of build gradle file in Android?

Android Studio uses Gradle, an advanced build toolkit, to automate and manage the build process, while allowing you to define flexible custom build configurations. Each build configuration can define its own set of code and resources, while reusing the parts common to all versions of your app.

How many types of Gradle build files do we have in Android?

Each module has its own build file, so every Android Studio project contains two kinds of Gradle build files.

How to add jar as a library on Android Studio?

This example demonstrates how to add jar as a library on Android Studio. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 4 − Add the following code to res/layout/activity_main.xml.

How do I import a Gradle library into Android Studio?

Just click‚ synch the project with Gradle. Your library should be available for your project. Click on “ Import Existing Project “. Step 2: Select the desired library and the desired module. Then click finish. Android Studio will import the library into your project and will sync Gradle files.

How do I add a JAR file to a Gradle project?

To do this, simply download the relevant jar file and then drop it into the libs folder of your project. Now right-click that file and choose “Add as Library…” If you go and check inside your module’s Gradle build file, you should now see that the dependency has been added.

How to add external libraries to your Android project?

Almost every well-known Android library is available in a Maven repository and its installation takes only one line of code in the app/build.gradle file: Let’s add the external library to our project: Step 1: Create a new project using Android Studio and name it anything you want (GFG in this example) and hit the finish button.


3 Answers

A updated and somewhat more future-proof answer (since bootclasspath compilerargs have been changing in more recent JDKs):

  • Supposing you have taken system libraries like framework.jar and libcore.jar from aosp intermediates (generated when building aosp) and added them into a folder (such as system_libs) in your project, add the libraries to the compile classpath in build.gradle:
dependencies {
    compileOnly fileTree(dir: 'system_libs', include: ['*.jar'])
}

gradle.projectsEvaluated {
    tasks.withType(JavaCompile) {
        options.bootstrapClasspath = files(
            new File("./system_libs/framework.jar").path,
            new File("./system_libs/libcore.jar").path
        )
    }
}
  • Add a task to put referring to the Android API Platform in the last position in app.iml, this way gradle will take into account your system libs first and Android SDK last:

preBuild {
    doLast {
        def imlFile = file(project.name + ".iml")
        println 'Change ' + project.name + '.iml order'
        try {
            def parsedXml = (new XmlParser()).parse(imlFile)
            def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
            parsedXml.component[1].remove(jdkNode)
            def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform"
            new Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])
            groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
        } catch (FileNotFoundException e) {
            // nop, iml not found
        }
    }
}

Based on @Bertrand's answer

like image 79
Oliver Scott Avatar answered Nov 15 '22 18:11

Oliver Scott


I solved the issue from this post to build application with system libraries :

Supposing you have added system libraries like libframework.jar and libcore.jar in app/libs :

  • add Xbootclasspath to your top level build.gradle :

    allprojects {
    
        gradle.projectsEvaluated {
            tasks.withType(JavaCompile) {
                options.compilerArgs.add('-Xbootclasspath/p:app/libs/libframework.jar:app/libs/libcore.jar')
            }
        }
    }
    
  • in you app build.gradle, use provided :

    dependencies {
        provided fileTree(include: ['*.jar'], dir: 'libs')
    }
    
  • in the same app build.gradle, add a task to put <orderEntry> referring to Android API 25 Platform in the last position in app.iml, this way gradle will take into account your system libs first and Android SDK in last resort :

    preBuild {
    
        doLast {
            def imlFile = file(project.name + ".iml")
            println 'Change ' + project.name + '.iml order'
            try {
                def parsedXml = (new XmlParser()).parse(imlFile)
                def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
                parsedXml.component[1].remove(jdkNode)
                def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform"
                new Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])
                groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
            } catch (FileNotFoundException e) {
                // nop, iml not found
            }
        }
    }
    
like image 34
Bertrand Martel Avatar answered Nov 15 '22 19:11

Bertrand Martel


You can't do what you want in Gradle(*), at least for the foreseeable future at the time this is written. A few problems are getting in your way:

  • Gradle doesn't do ordering of dependencies in the build classpath the way that Eclipse does, which is what you were doing to put your classes ahead of android.jar. Gradle has the philosophy that you should be explicit about dependencies in your build so what's going on is understandable and repeatable; systems that rely on classpath ordering tend to be subtle and fragile. So what you would need to do is to tell Gradle that your project depends on your custom classes and not android.jar, but the plugin's DSL doesn't give you the means to do that. There's some discussion at http://forums.gradle.org/gradle/topics/classpath_ordering_again and http://www.gradle.org/docs/current/userguide/dependency_management.html
  • Another way of looking at it is a reference to android.jar is hardcoded into the Android Gradle plugin, so you can't get at that dependency and replace it with something else.

(*) Having said all that, nothing is impossible -- you could make it work, but you're going to have to hack something together, so it's going to be more trouble-prone than the Eclipse approach, and tougher to maintain in the face of SDK and tooling updates. And when something goes wrong you'll be on your own.

  • You could assemble your own custom SDK with your own android.jar.
  • You could hack the Android Gradle plugin. This approach would definitely be tough -- the learning curve there is pretty steep, and the code is under heavy development, which would be a maintenance burden as you try to stay up-to-date.

I hesitate to offer much more insight into either of those approaches, partly because I don't know a lot about it and could pretty easily give you bad advice, and partly because I don't want inexperienced developers seeing this to think it's an awesome thing to do. But if you figure it out, it would be very much worthy of writing up, because I've seen this sort of question before, so you're not the only one.

like image 33
Scott Barta Avatar answered Nov 15 '22 19:11

Scott Barta