Dependency management

This will be a series, so if you haven’t read my previous posts, check out the following:

Dependency management is where Gradle shines most. In the best case, you simply add one line of code to your build file and Gradle will automatically download the relevant JARS from a remote repository and ensure that you can use them properly. Gradle can do even more for you, including eliminating the same JAR packages for you when you add multiple identical dependencies to your project. In this chapter we will learn the following:

warehouse

When we talk about dependencies, we are usually talking about remote repositories, like those that are specifically made available to other developers. Manually managing dependencies will cause you a lot of trouble. You must locate the dependency file location, then download the JAR file, copy the file into your project, and then reference them. Often these JAR files don’t have a specific version number, so you have to memorize their version number so that when it comes time to update, you know which version to replace. You must also put the dependency package on SVN or Git so that your colleagues don’t have to manually download the dependency Jar.

These problems can be solved by using a remote repository, which can be treated as a collection of files. Gradle does not add any repositories to your project by default. So you need to add them to the repository method body. If you’re using Android Studio, the tools have it all ready for you:

repositories {
    jcenter()
}
Copy the code

Gradle supports three different repositories: Maven and Ivy and folders. Dependencies are downloaded from these remote repositories when you perform a build. Of course Gradle keeps the cache locally for you, so a particular version of dependencies only needs to be downloaded once.

A dependency needs to define three elements: group, name, and version. Group means the name of the organization that created the library, usually the package name, and name is the unique identifier for the library. Version is the library version number. Let’s see how to declare dependencies:

Dependencies {the compile 'com. Google. Code. Gson: gson: 2.3' compile 'com. Squareup. Retrofit: retrofit: 1.9.0'}Copy the code

The code above is based on Groovy syntax, so the full statement should look like this:

Dependencies {compile group: 'com.google.code.gson', name: 'gson', version:'2.3' 'com.squareup.retrofit', name: 'retrofit' version: '1.9.0'}Copy the code

Predefined for your repository

For convenience, Gradle predefined three Maven repositories by default: Jcenter and mavenCentral and the local Maven repository. You can declare them both:

repositories {
       mavenCentral()
       jcenter()
       mavenLocal()
   }
   Copy the code

Maven and the Jcenter repository are two well-known repositories. There is no need to use both of them. Here I recommend using JCenter, a branch of Maven’s central library, so you can switch between the two repositories at will. Of course, JCenter also supports HTTPS, whereas maven repository does not.

The local Maven library is a collection of all the dependencies you’ve ever used, although you can add your own. By default, you can find the.m2 folder in your home file. In addition to these warehouses, you can also use other public or even private warehouses.

Remote warehouse

Some organizations create interesting plug-ins or libraries that they prefer to keep in their Own Maven libraries rather than in the Maven central libraries or JCenter. So when you need these repositories, all you need to do is add the URL to the Maven method:

repositories {
       maven {
           url "http://repo.acmecorp.com/maven2"
       }
}
Copy the code

The Ivy warehouse can do the same. Apache Ivy is a well-known dependency management tool in the Ant world. If your company has its own repository and they need permission to access it, you can write something like this:

repositories {
       maven {
           url "http://repo.acmecorp.com/maven2"
           credentials {
               username 'user'
               password 'secretpassword'
           }
        } 
   }
   
Copy the code

Note: This is not a good idea. The best way to do this is to put these validations in the Gradle Properties file, which we covered in Chapter 2.

Relying on local

There may be cases where you need to manually download jar packages, or you want to create your own library that you can reuse across different projects without having to publish to public or private libraries. In this case, you probably don’t need network resources, so I’ll show you how to use these JAR dependencies, how to import the SO package, and how to add dependent projects to your project.

File is dependent on

If you want to add jar files as dependencies for your project, you can do this:

dependencies {
       compile files('libs/domoarigato.jar')
}
Copy the code

It would be silly to do this, because when you have a lot of these jars, you can rewrite it as:

dependencies {
       compile fileTree('libs')
 }
 Copy the code

By default, new Android projects have a lib folder and are defined in dependencies like this (adding all jars in the libs folder) :

dependencies {
       compile fileTree(dir: 'libs', include: ['*.jar'])
}
Copy the code

This also means that in any Android project, you can put a JAR file in the LIBS folder and it will automatically be added to the compile path and the final APK file.

Native Pack (SO Pack)

Libraries written in C or C ++ are called so packages. Android plugins support Native packages by default, so you need to put the. So files in the appropriate folder:

App ├ ─ ─ AndroidManifest. XML └ ─ ─ jniLibs ├ ─ ─ armeabi │ └ ─ ─ nativelib. So ├ ─ ─ armeabi - v7a │ └ ─ ─ nativelib. So ├ ─ ─ MIPS │ └ ─ ─ Sci-imp. So ├ ─ x86 ├ ─ sci-impCopy the code

Aar file

If you want to share a Library that uses the Android API, or contains Android resource files, then an AAR file is for you. Dependency libraries are the same as application projects. You can use the same tasks to build and test your dependency projects, but they can also have different builds. The difference between an application project and a dependency project is the output file. An application project generates an APK file that can be installed on an Android device, while a dependency project generates an.aar file. This file can be used as a dependency by the Android application project.

Create and use dependency engineering modules

The difference is that you need to add different plugins:

 apply plugin: 'com.android.library'
 Copy the code

There are two ways to use a dependency project. Either use it directly as a module in your project, or create an AAR file that can be reused by other applications.

If you use it as a module, you need to add it as a module in settings.gradle:

   include ':app', ':library'
   Copy the code

We’ll call it library for this purpose. If you want to use this module, you need to add it to your dependencies, like this:

   dependencies {
       compile project(':library')
  }
Copy the code

Using AAR files

If you want to reuse your Library, you can create an AAR file and use it as your project dependency. When you build your library project, the AAR file will be generated under Build /output/aar/. To use this file as your dependency package, you need to create a folder to put it in, let’s call it aars folder, copy it into this folder, and add this folder as your dependency library:

repositories {
    flatDir {
        dirs 'aars' 
    }
}
Copy the code

This way you can rely on all aar files in this folder, and in the meantime you can do this:

 dependencies {
       compile(name:'libraryname', ext:'aar')
}
Copy the code

This tells Gradle, in the aars folder, to add a file called LibraryName with the suffix aar as a dependency.

Concept of dependency

configuration

At some point, you may need to work in harmony with the SDK. In order to compile your code successfully, you need to add an SDK to your build environment. You don’t need to include the SDK in your APK, because it already exists on the device, so the configuration comes, and we will have 5 different configurations:

  • compile

  • apk

  • provided

  • testCompile

  • androidTestCompile

Compile is the default, which means that all dependency packages are included. In APK, the dependencies of compile will exist.

Apk means present in apK, but not included in compilations.

Provided means compilation support, but does not write to APK.

TestCompile and androidTestCompile add additional library support for tests.

These configurations will be used in test related tasks, which can be very useful for adding test frameworks such as JUnit or Espresso, because you only want them to appear in test APK, not production APK.

In addition to these specific configurations, the Android plug-in also provides configurations for each build variant, which makes configurations such as debugCompile or releaseProvided possible. This is useful if you want to add a logging framework for your debug version. I’ll cover all of this in more detail in my next blog post.

Dynamic version

In some cases, you may want to use the latest dependency packages when building your app or library. The best way to implement it is to use a dynamic version. I’m going to show you a few different dynamic control versions:

Dependencies {the compile 'com. Android. Support: support - v4:22.2 +' compile 'com. Android. Support: appcompat - v7:22.2 +' compile 'com.android.support:recyclerview-v7:+' }Copy the code

In the first line, we tell Gradle to get the latest production version. In the second line, we tell Gradle that we want the latest minor version and that the minimum version number is 2. In line 3, we tell Gradle to get the latest library.

You should be careful to use dynamic version, if when you allow gradle to select the latest version, could lead to a selected depend on the version is not stable, it will have a lot of problems for the construction, the worse you may get different on your server and private PC depends on the version, this directly lead to your application are not synchronized.

If you use dynamic builds in your build.gradle, Android Studio will warn you about potential problems with dynamic builds, as you can see below:

Android Studio UI operations depend on libraries

With Android Studio, the easiest way to add a new dependency package is to use the Engineering Structure popbox. Open the interface from the File button, navigate to the dependencies navigation bar, and then you can see your current dependencies:

When you want to add a new dependency package, you can click on the little green button, you can add other modules, files, and even search the Internet.

Using Android Studio’s interface makes it easy to browse through all dependencies in your project and add new ones. You don’t have to manually add code to build.gradle, and you can search for dependent resources in the JCenter library.

conclusion

In this chapter, we learned about various ways to add dependencies, we learned what repositories are and how to use them, and we learned how to use JAR files without using repositories.

You now know about dependency package property configuration, dynamic versioning, and so on.

We also talked about building app variants in multiple environments. In the next chapter, we’ll learn what build variants are and why they’re important. Build variants make it easier to develop tests and distribute apps. Understanding how variants work can speed up your development and distribution efforts.