I am using Android v4 library. There are some unused modules such as accessibility that I would like to remove from the dependency. I saw this link which says I can use ProGuard to do that, but I would like to know if there is something I can add to the gradle to explicitly set the removal.
android-support-v4 remove unused classes
Appreciate your help.
ProGuard does it by itself by default, but you may also "fix" your dependency using more specific lib instead of whole v4 package. take a look on options, maybe just one or two options will be sufficient for you
Related
I have a library and it depends on Android-support-v4 (The JobIntentService class). I'm going to use it in Basic4Android.
There are two ways of adding supprt-v4 dependency to project:
Add <dependsOn>com.android.support:support-v4</dependsOn>
to library xml.
Add
dependsOn>support-annotations</dependsOn>
<dependsOn>support-compat</dependsOn>
<dependsOn>support-v4</dependsOn>
<dependsOn>support-core-ui</dependsOn>
<dependsOn>support-core-utils</dependsOn>
<dependsOn>support-fragment</dependsOn>
<dependsOn>support-media-compat</dependsOn>
to that xml.
If I use the first way, I can't find JobIntentService. If I use the second way it's fine, but It will have a conflict with the AppCompat library.
So how an I have a complete code of support-v4 without experiencing conflicts?
I know that JobIntentService exists in support-compat part of android-support-v4, but adding it beside com.android.support:support-v4 still causes duplications.
Since the first way uses Maven artifacts to get your library from Jcenter, it might download an old version that does not include this class in it's class path.
To resolve this clear libraries of B4A placed in the sdk m2repository
folder named b4a_remote, delete it and let the B4A redownload the files. Therefore it will download fresh and updated libraries that contain this class.
I just created a new library, Powerful Image View.
My library is a custom AppCompatImageView, so I need the appcompat-v7 library. And here comes the question:
How should I add it to my library?
Should I use 'compile', or 'provided' and let the user add the library to its own dependencies?
And how should i handle different versions of the libraries used, since i'm not depending on a specific version?
I added to the library's gradle file this line:
provided 'com.android.support:appcompat-v7:+'
I'd like to know your thoughts about this :)
Should I use 'compile', or 'provided' and let the user add the library to its own dependencies?
I would use compile and make sure that the developer using your library understands that your library relies upon appcompat-v7, as that in turn places lots of other requirements (e.g., using AppCompatActivity, using Theme.AppCompat).
And how should i handle different versions of the libraries used, since i'm not depending on a specific version?
Well, you are requiring some version. AppCompatImageView does not exist in all versions of appcompat-v7. I recommend depending upon a concrete version (i.e., not +), ideally the latest-and-greatest version.
We have developed an android library (aar) using Java and it depends on android support library v4. In fact, we have extended ViewPager (android.support.v4.view.ViewPager) class and consumed it in our library’s GUI.
We have applied proguard on the library and it works fine with our test apps but we have a customer that has developed its android app in native C++ and they are going to integrate our component into their app and there is an issue on build.
They receive com.android.dex.DexIndexOverflowException on build which is a sign of having more than almost 64K methods that are allowed in a single dex.
They asked us to use fewer or smaller dependencies as they have to include our component dependencies into their build setting and one of their suggestions is that we should extract ViewPager out of android support source and put it in our component source code.
Now the questions are
If we extract ViewPager out of android source and add it to our
library source code then will it reduce the amount of methods to
prevent mentioned exception? Is it a good practice to do that?
What is the best way to resolve this issue?
Thanks
If we extract ViewPager out of android source and add it to our library source code then will it reduce the amount of methods to prevent mentioned exception?
Probably not, at least for release builds. Your customer should have configured ProGuard, which will identify and remove unnecessary code pulled in via libraries.
Is it a good practice to do that?
No. Your customer should know better than that.
What is the best way to resolve this issue?
Mostly, it is not your problem. It is your customer's problem. Your customer is blaming you, but there is no evidence in your question that your library is a significant source of the customer's DEX method references.
Your customer should be configuring ProGuard, and your customer should use the APK Analyzer in Android Studio 2.2+ to see where their method references come from.
You, in your library, could:
Try to use more focused dependencies than support-v4. ViewPager itself is in the support-core-ui artifact. However, if you are using FragmentPagerAdapter or FragmentStatePagerAdapter, in addition you will need either support-fragment (if you are using the v4 edition of those classes) or support-v13 (if you are using the v13 edition of those classes).
Use the APK Analyzer on some demo project that you create that uses your library, so you can see how many DEX method references that your library uses, to see if you are really a significant source of such references.
Suggest ProGuard settings for your customer that will keep required classes of yours, to help them use ProGuard effectively with their app.
You can set jumboMode in your build.gradlefile like this:
dexOptions {
jumboMode true
}
This option will allow you to have 32it wide string references in your .dex file. Thus you can have 2^32 referenced strings in your project.
Hope it helps.
Available options are :
Yes, you can extract ViewPager from support library. ViewPager import some files from support library that are also required to be extracted. This will reduce method count with significant difference.
You can also use exclude parameter in dependencies in build.gradle file.
compile ('com.android.support:recyclerview-v7:+') {
exclude module: 'support-v4'
}
While developing an Android Library, if I add v7 Support Library as an dependency to use Toolbar class only, then would the final .aar file contain only the methods of Toolbar class and the related classes only, or it will contain that of Entire Support Library which wouldn't be in any use?
It'll contain the entire support library. In order to remove the unused classes and methods you should use ProGuard. Check out the official guide
about code and resource shrinking.
It will be completely included in your aar. In order to do it in right you you should use provided, e.g.:
provided 'com.android.support:appcompat-v7:+'
In that case users of your library will use there own support library and will not have the same code of support library which will go with your lib.
An unreleased android library I am working on has a third party networking library in it - OkHttp in this case.
Projects that use this library as a dependency also are now able to create objects with that networking library.
Can I limit or disable access to the networking library contained within my library?
You could make the dependency transitive however if your code hits the missing code inside their app it will fail ClassNotFound or MethodNotFound
dependencies {
compile('com.squareup.okhttp3:okhttp:3.2.0') {
transitive = false
}
}
Short of that once the code is packaged with your lib it's available to anyone who wants to use it from your lib.
This still won't solve the problem as you would like but you could use proguard to rename the okhttp classes. Users of your lib could still call the okhttp classes but they would be renamed by proguard to something like a,b,c,...
What you want to do is shade the dependency. Here's a description from a blog post about shading dependencies in Gradle:
To Shade a library is to take the contents files of said library, put
them in your own jar, and change their package.This is different from
packaging which is simply shipping the libraries files in side your
own jar without relocating them to a different package. The term
fatjar is commonly used to refer to jars that have the application as
well as its dependencies packaged or shaded into them.
It's easy to do for smaller libraries. I could image it might be difficult for a large library like OkHttp. You can do it manually by simply copying the files into your project and changing the package. There are also some scripts that will do it automatically. They usually use Jar Jar Links.
Normally be default you don't have the dependencies like that:
compile rootProject.ext.okhttp
compiled in your jar only your sources are. So OkHttp classes will not be in your lib.
I have exactly the same case. I use gradle to build and upload to maven.
You can check here
So if your intention is to have the exact dept version in the package and to be hidden you just need to include it in you project as a module and to change some things like the package of OkHttp to avoid conflicts and also the access to currenly public okhttp members. OkHttp is using Okio so you may want to privatize it too.
Note that this kind of shadowing + hiding functionality of the shadowed class can be useful for framework dependencies(ensuring all depts in runtime available) but it is increasing the size of your libs and will not be the best option for apps using your lib as they anyway ensure packaging required depts in the apk.