Android Library integration and APP size - android

I am using the AppIntro library,and integrated it via build.gradle as normally suggested.
But since the library classes are locked this way and I want to be able to edit every class manually I have the following questions.
1. What is the go to way of including a library such as AppIntro in a way
that I will be able to edit every class.
2. Since I want to minimize the final size of my Android App, does different integration of librarys have an impact here or does the magic during build process exclude stuff that is not needed ?
I am simply not surf if downloading the complete github .zip is necessary or even the right way to do it, since it also includes a sample app and other unnecessary stuff.

What is the go to way of including a library such as AppIntro in a way that I will be able to edit every class.
Grab the sources and add to your project as separate module.
Since I want to minimize the final size of my Android App, does different integration of libraries have an impact here or does the
magic during build process exclude stuff that is not needed
ProGuard shall strip all the library code (but also your own code too :) that are not referenced (that's why it's important to sometimes tell it not do to that if you i.e. need code that rely on reflection to work.

Related

How can I use specific classes when building an apk with Android Studio?

I searched a little about this here but didn't found anything that helps me, maybe because it's impossible but I need confirmation.
The situation is the following:
I have an android app that integrate with many mobile POS, these card machines, and because I have many classes to integrate with these machines, the app became heavy for some POS stores, like Stone.
I saw that it's possible to impplement the libs modules and dependencies for specific flavors with android, so I would generate an specific appp, with just the classes that this integration use and nothing more, but I have everything together now, just like in the pics.
And when I build an app that will be used with Stone, for example, it will put all integrations in the JS interface.
I stated changing it, imlementing by flavor but as the implementation is per integration now, the Cielo class starts having problems with its dependencies because, as the app will be for Stone, it doesn't download the Cielo dependencies. The generation process crash.
When I started changing the structure, I manage to make the gradle build work, but after that, everything crashes.
There is something I can do ? Maybe impost only when the Cielo package really exists, or something like that.
If its needed to change the entire structure, it's ok, I just need to make it smaller but still in one place.
Thanks!
I tried useing flavors and separating the source sets alongside main directory, like:
-main
--assets
--java
-cielo
--java
-stone
bus it still have a problem when building because the import inside my main class.
You can split your application to multiple parts:
Main application which implements the app's features except an integration.
Android service API which defines API between the main application and an integration service
Integration services one for every platform. Each service have to implement API from point 2 to provide required contracts to the main application.
Finally you can deploy the main app and only one required integration service.

Export existing android app as aar (like a library)

Background: I have an android application that has been published in GooglePlay and I want to create SDK from that existing application so that others can use it as a library inside their apps.
So far: I was able to generate .ARR file from the existing app source code with little tweaks. and it is working pretty good.
The problem: is I have some sensitive information stored inside my app
since I made .arr file from my app codebase I'm little worried that they can easily get access to my SharedPreferenceManager (util class of mine to deal with SharedPreference) DataBaseManager so on and they can subclass library class and tweak the behaviors
So How can I avoid library users not to misuse my library to exploit my existing app?
is there any other way to export my app as a library?
The basic process would be as follows:
Figure out what you want to expose in your SDK
Move all of this into an android library module
Deploy the AAR
Can you explain a little more what you mean by "I'm little worried that they can easily get access to my SharedPreferenceManager (util class of mine to deal with SharedPreference) DataBaseManager so on and they can subclass library class and tweak the behaviors" ?
You can always utilize obfuscation techniques and finalize classes to make it difficult. I don't think you can guarantee absolutely no misuse, but I am not sure how this would effect your application. If you have a server, for instance, then you would still control the software there and be able to sanitize and sort through the input.

Prevent reaching 65k methods in Android

Every unconsidered usage of external library results in Gradle error about reaching 65k methods. So I'm wondering what is the best solution to prevent this, and I would like not consider using Proguard custom settings.
What comes to my mind (of course if we are using open source libraries) is just downloading code and putting it to our project manually. Then we can delete unused classes and methods. It looks like we are playing Proguard role and it's time consuming.
Question
But what is the difference between using Gradle to fetch jars and
putting code manually? Or is it any difference in performance?
I will be thankful for any best practices in creating project with many libraries.
Note: I would like to stop thinking for now about Proguard custom settings, because it often produces warnings, where omitting them looks a bit weird for me by e.g. -dontwarn. Also I'm a bit afraid of using MultiDex support, which I thougt is not recommended.
One thing you can do in gradle is to get very specific about what code modules you're including.
For example:
compile 'com.google.android.gms:play-services:8.4.0'
will include a lot more stuff than just...
compile 'com.google.android.gms:play-services-location:8.4.0'
Generally it's best to let gradle manage the external dependencies. The biggest reason is that you can rest assured that you're getting a snapshot of the code tied to a specific version. If you just manually import code, it's very easy to lose track of which version of the code you're working with. A big risk to modifying (or selectively including) code from a 3rd party is when the 3rd party updates their code, perhaps to fix a major bug caused by a new version of Android, and they included some changes that botch your manual tweaks. Now you have more a complex problem on your hands than if you had just included it as a gradle dependency.

"Library projects" in iOS

Some time ago I created and Android app. Then I needed to create very similar app (functionality-wise) with some cosmetic, branding and small-scale functionality changes. I refactored the original app as a library project, created an app that used this library project and recreated the original functionality. Then I created a new app that used that same library project and also implemented the small-scale changes required for the second app. This worked perfectly fine. Now if a change is needed, it's very easy to implemented it in multiple apps: I just change the library project and recompile all the apps.
I also had the original application available for iOS - and need to make the second app available for iOS. I could, naturally, copy the project, make the changes and create another apps. However this would mean double work if I needed to change something in the core functionality. I'd like to be able to refactor the iOS project/app similarly to the Android one, but not sure how to go about it - or if such functionality is even available. Any suggestions are much appreciated.
You can create a Single project with differents targets.
Then, you will have target A, and B for example and CoreFile files that are common for all targets.
Let's suppose you have HomeViewController with some slightly differences.
You can create a single interface HomeViewController.h and two implementation AHomeViewController and BHomeViewController, both extending BaseViewController.
Then open AHomeViewController, and on FileInspector at 'Target Membership' mark only target A. On BHomeViewController you do the same. Image 1, illustrate what you have to do (names are differents from the example because it's a real example from one of my projects).
If for some reason you have need to know what's targets are you using you can define it using Preprocessor Macros on Target -> Build Settings. As illustrate by Image 2.
Then you can use #ifdef APP_CB to check the current target.
As was mentioned you can really regulate target membership[About] of every file which you add. But in my opinion is better to create a separate framework(library) and add it as dependency
[Swift consumer -> Swift dynamic framework]

Manage code/build for Android app stores (Google/Amazon/etc)?

I have an Android app that's downloaded primarily from Android Market (now, Google Play). We made a few tweaks to the source and also submitted to the Amazon App Store to see what sort of traction it gets. I'm now looking for a sustainable way to develop from a common code base and yet build so that I can submit to either/both.
Amazon's store has some restrictions about available APIs, and hence I'd like to conditionally remove/modify features from that version. Since Java doesn't support traditional conditional compilation, and conditionally including files in Eclipse doesn't seem trivial (is it even possible?), I wanted to ask what others are doing to solve this.
Admittedly, I'm no Eclipse/Java expert so feel free to school me.
What I'm looking for in a solution:
Building/debugging using Eclipse.
Static code files, with environment/settings toggles to control what to build.
No duplicate code or conditional logic in code to pick code flow at runtime
Is this something you've solved for Android apps specifically, or for other Java/Eclipse based projects? Suggestions for where to begin?
It's quite easy to do in the newest versions of ADT (version 17), though I do find it makes compilation a bit longer:
Create a new Android project (proj-A)
Go to Project->Properties, select Android, and check "Is Library"
Move all your common code to proj-A, import all the necessary libraries
Create a new Android project for Google Play (proj-B)
Go to Project->Properties, select Android, and add Proj-A to the Library
Repeat #4&5 for the Amazon version
If you have some variables that should be set differently for each sub project (i.e. boolean GOOGLE_PLAY_VERSION to enable Google Play specific functions), you have to create another project to contain these values since you can't have projects that reference one-another in a circular fashion. You can solve this by adding the following steps:
Pull all of your sub-project specific variables into one or more Classes that just serves as container(s) for these variables
Create a "dummy" Java project (dummy)
Config proj-A to add a new Source link to the bin directory of dummy
Add the config Classes in each sub-project with project-specific changes
Profits!
Note that the variables in dummy should not be set as final, otherwise it will override sub-project's setting.
This may seem like quite a bit of up-front work, but has worked quite well for me as far as version control goes.
Edit:
Now with Google's move to Android Studio & Gradle, it may be better to move to that if you are starting a new project if you want to support multiple APKs, see Android dev site's Building Your Project with Gradle#Work with build variants. It definitely doesn't hurt to evaluate that option before deciding.
Unfortunately, it's sort of a convention in Android to change flow at runtime based on what would be in C/C++-land conditional compilation.
Our app has to maintain different behavior for different API levels, so we've created some application-level constants that are initialized statically based on API-level information available to us, and used throughout the code. This is the way that Google does things in their examples (for example, see the ActionBarCompat compatibility library, and in particular the factory method used here).
You could create an interface CustomBuild, and implement it in AmazonBuild and GooglePlayBuild, then use a static getBuild() method to switch functionality as necessary:
if(getBuild().shouldEnableFeatureX()){
doStuff();
} else {
doDifferentStuff();
}
Then all you've got to worry about switching between builds is a line or two of code in the factory along with maintaining which things you want enabled in which versions. Or you could include a different version of a static class CustomBuild for each build.
I'm going to second the suggestion of others above re: switching to something like Maven for building; it should make your life much easier once you have it set up.
I'm also going to say you should make the core of the app a library as suggested above, and have two different modules (one for amazon, one for play store) that depend on the library but each only contain the one custom factory file (or just a static class for each type of build that contains the same "should I do this thing?" methods... once you have the infrastructure it's just a matter of preference).
I haven't actually tried this yet, but it's something I've thought about.
How about using Eclipse's ability to link to files from a directory outside your workspace?
Start with one Eclipse project: for the sake of argument, say it's the Google Play version.
Now build a second project, beginning with asking Eclipse to link (not copy) the source files from your first project.
To develop the second project, add classes that subclass ones from the original project to realize your modifications. For resources, you can use some combination of includes, attribute overrides, and selectors.
Where it's not possible to subclass or extend, then obviously you'll have to just copy the original source file and hack on it. If you're really OCD about it, you can probably just maintain a patch set rather than a whole redundant set of files.
What do you think, will it work?
You may create manually two projects in Eclipse pointing to the same source folders but with different inclusion/exclusion filters and different target directories.
Then two Ant targets using properties to switch excluded files from javac fileset are enough to generate corresponding jar files.
The aim is to get a clean application for each target, without any code from the other one.
With features listed as pluggable behaviors in a property file or XML configuration, your runtime will adapt itself with the addition of menu entries.

Categories

Resources