TL;DR
build.gradle
dependencies
task.If you want to distribute your app on Google Play, you must properly comply with the license terms of the external library you used. Therefore, app developers need to know what external libraries their apps are using.
On Android, it's standard practice to use Gradle to deploy external libraries. Gradle will download to your local environment, including the libraries that the external library you want to use references (depends on). While Gradle hides the tedious work, you may actually be using an unexpected library.
build.gradle
//...
dependencies {
implementation 'com.android.support:appcompat-v7:28.0.0'
}
//...
ʻAppcompat-v7 is an almost indispensable library for making modern Android apps, and I think many people are using it. Did you know that apps that import ʻappcompat-v7
also import the libraries listed below?
There are a total of 30 libraries including ʻappcompat-v7. Keep in mind, these libraries are libraries where the user did not write ʻimplementation
, but just one line of statement that **'appcompat-v7 ʻimplementation
**.
In this article, I will explain how to find out the external libraries used in Android application production. It also explains how to check the Apache License 2.0 attribution notice, which is often applied to Android libraries.
This time, I will explain using the following dependencies as an example. Apache Commons Codec is added to the dependencies created as a result of proceeding with the Android Studio project creation wizard with the default settings. ..
build.gradle
//...
dependencies {
//Android Studio added by default
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
//add to
implementation 'commons-codec:commons-codec:1.11'
}
//...
Now, I will explain how to know the library you are using.
In fact, this can be understood by executing only one Gralde task. Let's run the ʻandroid Dependencies` task from the Gradle window.
Then, I think that the result came out in the Run window.
Let's take a look at the blocks that start with releaseRuntimeClassPath
.
androidDependencies execution result.
...
releaseRuntimeClasspath - Dependencies for runtime/packaging
+--- com.android.support:appcompat-v7:28.0.0@aar
+--- com.android.support.constraint:constraint-layout:1.1.3@aar
+--- commons-codec:commons-codec:1.11@jar
+--- com.android.support:support-fragment:28.0.0@aar
+--- com.android.support:animated-vector-drawable:28.0.0@aar
+--- com.android.support:support-core-ui:28.0.0@aar
+--- com.android.support:support-core-utils:28.0.0@aar
+--- com.android.support:support-vector-drawable:28.0.0@aar
+--- com.android.support:loader:28.0.0@aar
+--- com.android.support:viewpager:28.0.0@aar
+--- com.android.support:coordinatorlayout:28.0.0@aar
+--- com.android.support:drawerlayout:28.0.0@aar
+--- com.android.support:slidingpanelayout:28.0.0@aar
+--- com.android.support:customview:28.0.0@aar
+--- com.android.support:swiperefreshlayout:28.0.0@aar
+--- com.android.support:asynclayoutinflater:28.0.0@aar
+--- com.android.support:support-compat:28.0.0@aar
+--- com.android.support:versionedparcelable:28.0.0@aar
+--- com.android.support:collections:28.0.0@jar
+--- com.android.support:cursoradapter:28.0.0@aar
+--- android.arch.lifecycle:runtime:1.1.1@aar
+--- com.android.support:documentfile:28.0.0@aar
+--- com.android.support:localbroadcastmanager:28.0.0@aar
+--- com.android.support:print:28.0.0@aar
+--- android.arch.lifecycle:viewmodel:1.1.1@aar
+--- android.arch.lifecycle:livedata:1.1.1@aar
+--- android.arch.lifecycle:livedata-core:1.1.1@aar
+--- android.arch.lifecycle:common:1.1.1@jar
+--- android.arch.core:runtime:1.1.1@aar
+--- android.arch.core:common:1.1.1@jar
+--- com.android.support:interpolator:28.0.0@aar
+--- com.android.support:support-annotations:28.0.0@jar
\--- com.android.support.constraint:constraint-layout-solver:1.1.3@jar
...
The ʻandroidDependenciestask is a task that presents your app's dependencies. Normally, the run-time classpath of the release task matches the library you are actually including. Therefore, you can look at the
releaseRuntimeClasspath` to get a list of the libraries your app is using.
If you want to know more detailed dependencies, run the dependencies
task.
Dependency execution result.
...
releaseCompileClasspath - Resolved configuration for compilation for variant: release
+--- com.android.support:appcompat-v7:28.0.0
| +--- com.android.support:support-annotations:28.0.0
| +--- com.android.support:support-compat:28.0.0
| | +--- com.android.support:support-annotations:28.0.0
| | +--- com.android.support:collections:28.0.0
| | | \--- com.android.support:support-annotations:28.0.0
| | +--- android.arch.lifecycle:runtime:1.1.1
| | | +--- android.arch.lifecycle:common:1.1.1
| | | | \--- com.android.support:support-annotations:26.1.0 -> 28.0.0
| | | +--- android.arch.core:common:1.1.1
| | | | \--- com.android.support:support-annotations:26.1.0 -> 28.0.0
| | | \--- com.android.support:support-annotations:26.1.0 -> 28.0.0
| | \--- com.android.support:versionedparcelable:28.0.0
| | +--- com.android.support:support-annotations:28.0.0
| | \--- com.android.support:collections:28.0.0 (*)
| +--- com.android.support:collections:28.0.0 (*)
| +--- com.android.support:cursoradapter:28.0.0
| | \--- com.android.support:support-annotations:28.0.0
| +--- com.android.support:support-core-utils:28.0.0
| | +--- com.android.support:support-annotations:28.0.0
| | +--- com.android.support:support-compat:28.0.0 (*)
| | +--- com.android.support:documentfile:28.0.0
| | | \--- com.android.support:support-annotations:28.0.0
| | +--- com.android.support:loader:28.0.0
| | | +--- com.android.support:support-annotations:28.0.0
| | | +--- com.android.support:support-compat:28.0.0 (*)
| | | +--- android.arch.lifecycle:livedata:1.1.1
| | | | +--- android.arch.core:runtime:1.1.1
| | | | | +--- com.android.support:support-annotations:26.1.0 -> 28.0.0
| | | | | \--- android.arch.core:common:1.1.1 (*)
| | | | +--- android.arch.lifecycle:livedata-core:1.1.1
| | | | | +--- android.arch.lifecycle:common:1.1.1 (*)
| | | | | +--- android.arch.core:common:1.1.1 (*)
| | | | | \--- android.arch.core:runtime:1.1.1 (*)
| | | | \--- android.arch.core:common:1.1.1 (*)
| | | \--- android.arch.lifecycle:viewmodel:1.1.1
| | | \--- com.android.support:support-annotations:26.1.0 -> 28.0.0
| | +--- com.android.support:localbroadcastmanager:28.0.0
| | | \--- com.android.support:support-annotations:28.0.0
| | \--- com.android.support:print:28.0.0
| | \--- com.android.support:support-annotations:28.0.0
| +--- com.android.support:support-fragment:28.0.0
| | +--- com.android.support:support-compat:28.0.0 (*)
| | +--- com.android.support:support-core-ui:28.0.0
| | | +--- com.android.support:support-annotations:28.0.0
| | | +--- com.android.support:support-compat:28.0.0 (*)
| | | +--- com.android.support:support-core-utils:28.0.0 (*)
| | | +--- com.android.support:customview:28.0.0
| | | | +--- com.android.support:support-annotations:28.0.0
| | | | \--- com.android.support:support-compat:28.0.0 (*)
| | | +--- com.android.support:viewpager:28.0.0
| | | | +--- com.android.support:support-annotations:28.0.0
| | | | +--- com.android.support:support-compat:28.0.0 (*)
| | | | \--- com.android.support:customview:28.0.0 (*)
| | | +--- com.android.support:coordinatorlayout:28.0.0
| | | | +--- com.android.support:support-annotations:28.0.0
| | | | +--- com.android.support:support-compat:28.0.0 (*)
| | | | \--- com.android.support:customview:28.0.0 (*)
| | | +--- com.android.support:drawerlayout:28.0.0
| | | | +--- com.android.support:support-annotations:28.0.0
| | | | +--- com.android.support:support-compat:28.0.0 (*)
| | | | \--- com.android.support:customview:28.0.0 (*)
| | | +--- com.android.support:slidingpanelayout:28.0.0
| | | | +--- com.android.support:support-annotations:28.0.0
| | | | +--- com.android.support:support-compat:28.0.0 (*)
| | | | \--- com.android.support:customview:28.0.0 (*)
| | | +--- com.android.support:interpolator:28.0.0
| | | | \--- com.android.support:support-annotations:28.0.0
| | | +--- com.android.support:swiperefreshlayout:28.0.0
| | | | +--- com.android.support:support-annotations:28.0.0
| | | | +--- com.android.support:support-compat:28.0.0 (*)
| | | | \--- com.android.support:interpolator:28.0.0 (*)
| | | +--- com.android.support:asynclayoutinflater:28.0.0
| | | | +--- com.android.support:support-annotations:28.0.0
| | | | \--- com.android.support:support-compat:28.0.0 (*)
| | | \--- com.android.support:cursoradapter:28.0.0 (*)
| | +--- com.android.support:support-core-utils:28.0.0 (*)
| | +--- com.android.support:support-annotations:28.0.0
| | +--- com.android.support:loader:28.0.0 (*)
| | \--- android.arch.lifecycle:viewmodel:1.1.1 (*)
| +--- com.android.support:support-vector-drawable:28.0.0
| | +--- com.android.support:support-annotations:28.0.0
| | \--- com.android.support:support-compat:28.0.0 (*)
| \--- com.android.support:animated-vector-drawable:28.0.0
| +--- com.android.support:support-vector-drawable:28.0.0 (*)
| \--- com.android.support:support-core-ui:28.0.0 (*)
+--- com.android.support.constraint:constraint-layout:1.1.3
| \--- com.android.support.constraint:constraint-layout-solver:1.1.3
\--- commons-codec:commons-codec:1.11
...
ʻAndroidDependencies will tell you the library that will eventually be used in a bulleted format, while
dependencies` will tell you the dependencies in a tree format.
Use this to find out if you really need a library.
When I try to output the list with ʻandroid Dependencies, I get a lot of unknown libraries. Check out the Maven Repository (https://mvnrepository.com/) for such libraries. For example, if you look at ʻandroid.arch.lifecycle: viewmodel
, the following page will appear.
From this page, you can see that ʻandroid.arch.lifecycle: viewmodel is apparently part of an Android package named Android Lifecycle ViewModel and is distributed under the Apache License 2.0. Therefore, you can see that ʻandroid.arch.lifecycle: viewmodel
should follow the distribution conditions of Apache License 2.0.
I've explained it for a long time, but in fact, there are many Android Studio plugins that automatically output the above steps (and even create license display activities depending on the item **). Please refer to @ tyoro's article.
Some libraries that embed license displays in Android apps
You might be wondering, "If you do it automatically, you won't do it anymore?" However, there are some tasks that cannot be automated when displaying the license to use the library licensed under Apache License 2.0. It is a notice of belonging.
Apache License 2.0 stipulates that if the library you use has attribution, you must show its contents visibly in the documentation. Files containing the contents of this attribution are called NOTICE files, etc.
The trouble is that in the Android (Java) world, NOTICE files are generally distributed by embedding them in a jar or aar. Also, NOTICE files have no fixed file name or format. In other words, ** you need to look around each jar or aar to see if it contains a file equivalent to the NOTICE file **.
Below are the steps to check efficiently (?) Using Android Studio.
Project
from the combo box list to switch the display.You can see all the dependent libraries in Android Studio, right?
Now, let's check if there is a NOTICE file in the Android Lifecycle ViewModel.
If you dig into Gradle: android.arch.lifecycle: viewmodel-1.1.1
...
There was an unfamiliar file called ʻandroid.arch.lifecycle_viewmodel.version in
META-INF`, but when I looked inside, only the version information was really described as the file name.
Apparently there is no NOTICE file in the Android Lifecycle ViewModel as there are no other files.
Next, let's check if there is a NOTICE file in Commons-Codec of Apache.
If you dig into Gradle: commons-codec: commons-codec: 1.11 @ jar
...
I found NOTICE.txt
in META-INF
of commons-codec-1.11.jar
.
When you open NOTICE.txt
, you can see that the content of attribution (credit information) is written.
It seems that this description should be quoted in the license display.
This time, the NOTICE file existed with the path META-INF / NOTICE.txt
, but it is not uncommon for some libraries to exist with completely different file names and file paths.
Let's search patiently.
Distributing software that does not comply with the license terms may, in the worst case, be sued by the author and lead to trial. Handle the licensed software properly.
Recommended Posts