Im thinking about trying to build a complex android app structure for a game maybe or just for practice reasons. Im used to code in objective-c, so im not that much experienced in android...
Anyway in work, we structure our app on ios like this:
-core framework: handling all core items, navigation, datahandling, mechanisms, etc. its the same in all of our project
-project framework: its files are mostly relying (including) the core framework's files, extending/modifying them, and doing the project depending stuff
-skin framework: this contains all the resources and images, if we want to do a re-skinned project, we only have to alter this
-main project: this includes everything just bashing together everything into an app. just starts the application, nothing more, anything else is done by the different frameworks
So I wanted to do a similar structure on android, but I'm not sure that I'm even able to do it... I see that there is android project and library project, I can include them into eachother... but my questions are:
1: can I build a similar structure as on ios?
2: can I make for example a "core" library what contains the basics of mechanisms, and another library containing only the resources, and a third one (or the third could be the actual runnable project), what can get resources from the resource library, can distribute jobs to the core library, etc...
3: can I organize the resources as I like (so not to throw every picture into the drawable folder root for example). For example to have somehow a characters folder (i know i cant do forlders in the res folder), and map files into map folder, etc... My only chance to name them "properly"? (map_sheet_type_1, map_sheet_type_2, character_sheet_type_1, etc) (if its going to be a game, it would use opengl, lots of sprite drawing, etc)
or I should do everything in a single project, dividing everything into a lot of packages, and use libraries only for jobs like "how to transcode "A" object into "B" object" ?
Thanks for the answers in advance
although I've never developed a game before, but an app is an app:
yes
as you mention you have executable projects and libraries projects, libraries can use other libraries and the only thing that goes to the device is whatever the executable project is building. It's just important to remark that compiled libraries *.jar files resources cannot be used in your executable project (that's why the ActionBar Sherlock have to be used as a library-project). In order to use a resource placed in a library project the project must be with its full source code open in the Eclipse so it can be compiled together. That is because inside an app, there's only one R (resources) object, and during build all the resources from all the projects are put together.
unfortunately no. As you mentioned yourself the resources cannot be in subfolders and even their file names are restricted as they can only use lower case letters, numbers and _ (underline). Just be clever and organised, write a spec or something.
packages IS the way to organize a single project in Java. If you gonna use multiple or single is your choice. Usually you can encapsulate in a library-project stuff that can easily be re-used in different projects, and the final project will contain everything that is specific to that one app/game. I'll give you an example on the place I work, we have a KicthenLibrary that is a library-project that we use in every single Android app we do. That library already contains an excellent multi-threaded bitmap download and cache classes, we used to have a MapFragment (now deprecated) before Google released their MapFragment, easy Http GET/POST methods, etc. As you can see, all of those are stuff that can easily be re-used in several different projects.
And just as a last trick, http://www.eclipse.org/egit/ IMHO is much easier to use GIT directly from inside Eclipse.
Here are a couple links that should help you get started on this.
http://kasperholtze.com/android/how-to-best-organize-your-android-source/
http://bartinger.at/organization-tips-for-android-projects/
Also, when I worked at a start-up, we made an app for both iOS and Android. We started creating native apps for each, and ended up having somewhat different structure. Global information/variables were handled different, and I couldn't structure my files quite like iOS did. That said, Android structure isn't terribly hard to figure out, and I made a fair amount of sub-folders in my assets folder (for libraries and js and such). And yes, you can definitely have several libraries.
As for having several projects in several in one app, see this link How to create a single application from multiple Android projects
Related
I've been working with Android for quite some time, yet I have never seen any good explanations for this issue.
I'm working on an app with a number of artwork and sound files. Many of these files are temporary, are base files that future work will evolve from, or are large versions that will be split into multiple files later. I want to keep them under version control with this project, and I'd like to keep everything in the same place on my hard drive.
But I don't want these "work" files to end up in my apk. They are often huge and have nothing to do with the final product.
For most of my life (ie, before Android), I would simply have a subdirectory within my project called art_work_files. And this directory would be subdivided into all the various tasks. And git is fine with this, especially for SVG files (it even properly notes differences and changes).
But when I put these files in my Android Studio project, I get concerned that the AS will think these are somehow important and keep references to them--possibly even adding them to jar or apk files.
Yes, I realize that the final versions of the art needs to go in the res/drawing/ directories (and similar for sound and other resources). And I'm happy to do this final copy.
Am I over-thinking this, or is there a better way to organize and still keep Android Studio happy?
Since no one has answered this question in 7 months, I'll submit my solution.
I have created a directory under the main directectory (same level as java and res) called assets. Git recognizes this directory and will notice any files that are added, removed, or changed. I'm fine with using git to handle binaries btw.
For each type of asset, I make another subdirectory. Here's what it looks like:
app ->
libs
src ->
main ->
assets ->
font
ogg
png
svg
java
res
...
This seems to work fine and keeps everyone happy. I'm still curious how other people do this; I welcome your comments and answers.
TL;DR
I'm an android developer and I have essentially several copies of the same app that feature slight differences. Despite my best efforts I'm having to resort to copy-and-paste style modification for each app-copy (hereafter "flavor") whenever I need to roll out a single change to all of the apps. This is particularly heinous in Android because of the number of languages/file-types involved in a given app - C for native code, Java for regular code, .xml files for data, layouts, and os permissions, etc. Tricks I know to avoid copy-and-paste coding that work in Java or C alone won't extend to both at once, or over to the .xml files. I've been using Apache ANT with some success to create a custom build/ folder on the fly and include relevant files there for different build-targets, but it's a little cludgy, and there are some cases it just can't handle.
I'm wondering if there is a build system that could handle all of this for me; I'm open to any advice, though the solution I have in mind is particular to a sort of language-independent/filesystem #include approach, which for a given flavor at build time injects either whole files into a src/ tree, or else injects code fragments into various .java, .c, and .xml template files in that src/ tree.
A Really Long Explanation with Concrete Examples:
Examples of the differences between flavors: in the Google Store I have to use the Google in-app purchasing sdk; but in the Amazon store I have to use the Amazon in-app purchasing sdk. Different flavors are paired with different advertising partners. Certain flavors require different i18n language files; or graphics and layout assets for different devices; etc. etc. Any given flavor is essentially the base code, plus any number of these "add ons", where each add on requires a little bit of custom code and file additions to the src/ tree for that app. Whenever I need to change an add-on, I end up having to copy-and-paste the change in each flavor of the app that uses it, which is a terrible pain.
As a concrete example, imagine I have an android game and I have implemented a custom Flurry Appcircle ad view. This would typically involve the following:
The addition of "<activity>", "<service>", and/or "<uses-permission>" tags to the game's AndroidManifest.xml
The addition of various "<string>" lines for the ad in the apk's res/values-xx/strings.xml folder system, where xx is a language code (ie Spanish translations would go in res/values-es/strings.xml)
One or more image or layout resources in res/layout, or assets/, for the ad.
The actual Flurry Inc sdk in the form of a Java .jar file in libs/ - possibly multiple jar files if different hardware architectures need to be handled differently.
Java Code in the game's Activity class, e.g. in onStart or onStop, to query for an Appcircle ad and show it. To avoid code duplication, I would normally write this in a base class that surrounds all code in a "if(appcircleAdsEnabled(){...}", create a default implementation of that method that returns false, and #Override and return true in various children Activity classes.
This causes a few problems:
The Flurry .jar is now a dependency for the base class to compile whether or not the ads are enabled or not in any given flavor. I can hope that the builder notices code or resources are unused at build time and removes it from the final apk; but there are no guarantees, and failure leads to (A) bloated final binary size and (B) potential P.R. issues or worse (especially from automated scanners searching for code inclusions - in a slightly different example, I'd have a hard time assuring the Amazon App Store that "yes Google Play Billing is there but it's not used.")
Because of the way Android turns resource files into java constants, and in the same way as (1), the res/* files may also become unnecessary dependencies of all games deriving from this Base Class.
Some libraries/methodologies I've found insist on their code being added in specific places or in specific ways which precludes the base class approach altogether.
For each individual game I still have to at least edit its AndroidManifest to "turn this on" and request relevant OS permissions necessary to show the ad.
It's tedious to remember which "add on" goes with which changes in which files. For instance, in any given flavor's AndroidManifest.xml, I can't keep track of which permissions are needed by which add ons. If I remove the Flurry add on, do I still need the INTERNET permission for something else?
What I'm hoping exists, and what I'm asking about, is if there's some way to inject files and code fragments into/on-top-of some skeleton file system, each add-on composed of a collection of such files and code fragments and injected dynamically at build time, with the build system merging lines across multiple add ons, and handling dependency inclusion on the fly. IE for my Flurry Ad add-on I would have:
Some collection of files 'FILES' that includes my xml additions to various .xml files (like AndroidManifest.xml), my code additions to various .java files (like the Activity subclass), and in some cases whole files themselves to be injected in various places (like the ad layout files)
In some skeleton template file tree, incomplete versions of e.g. AndroidManifest.xml, MyActivity.java, etc. with something like a language-independent #include syntax indicating that data from FILES will go there.
Also in that template file tree, directories in src/ with 'missing files' that will be copied in dynamically at build time from FILES
Some sort of build directive script for FILES indicating what goes where when this add-on is included, to take the skeleton template file tree and turn it into a fully fleshed out build/ tree.
And again, ideally it would be able to handle multiple "add ons" at the same time; ie I might have some FILES for this Advertiser, and some FILES for that billing provider, etc. etc., and a given product is just a list of which modules it includes, the build system magically knitting them together at build time.
This seems like exactly the problem the Gradle Build Variants system was designed to solve - it handles merging multiple versions of the AndroidManifest.xml, resources, and Java packages together into one or more separate apps. Specifically, the Multi-flavor variants seem to cover your requirements for combining multiple features together in various ways.
Gradle is offered as part of Android Studio, an IntelliJ based IDE specifically built for Android Gradle projects. You may consider reviewing one of the many Gradle Build guides if you are not familiar with Gradle.
in our company we are creating a product that is sold to different customers only changing visuals aspects (logos, trademarks, text, etc ...). We doubt how to handle this as we need to maintain a base (with their testings) and customized versions of these products (different package name and some modifications asides).
The more difficult for us is we handle this with Git and projects libraries that need to keep together. We need to keep easy to create new products and maintain updates for each one quickly
which workflow do you recommended to handle this? we have a mix of git + submodules + branches + libraries projects, but it's hard to create an android libproyect base
I don't fully understand your question so if you could write some more info it would be useful for others to help you. The part I understood was the problem of managing multiple projects that have same code but different resources and manifest files. On our project we had a similar problem developing for 3 different servers where code would stay the same but links, api keys and package names would need to change, even logo images might need to be different sometimes adding "integration icon/development icon" etc. What I did in this case was to create one Android library project where all the code and resources that are shared are stored and in our case 3 other projects that reference the library and have special res/drawable folder and strings in value folder where api keys and other settings are stored. This turned out to be great fit for our purposes since you can just pick a run configuration for project to be run and Android will load required resources. You could do this for any number of projects without any files being duplicated and taking space in your git repository. This approach actually allows you to let your designers change drawables for diffident projects by putting different images in folders without or with just a little involvement from developers. If you are skill full you could even write some ant scripts that build and sign projects for them so they can test on devices to see how real app looks.
I have a small Android application that uses different sets of files (a couple of images, a small SQLite DB and a couple of XML files) depending on the specific task at hand.
I know I can include my files into the main application APK using resources or assets but I would be happy to distribute them in a separated APK.
How can I create a data-only APK file?
How can I distribute it? In particular, do I have to do anything special for a data-only package (for example for associating it to the main application package in some way)?
(I'm intentioned to give the user a link to the data package and ask him to install it. No automatic installation required.)
How can I install my files into the internal or into the external storage area of my application? Is it possible at all to install files into the internal storage area created by the main application installer? Do I have to set any particular permission for this?
My approach to this would be to create a wrapper app that's nothing but a content-provider and serves up the files per request by your main app. This would allow you to supply different data packages for the user -- you could even have your main app select between those relatively easily.
It looks like that the commonly accepted way to have the same application with different contents (or styles, or configurations) is to use an Android Library Project for the common code (that is: the whole application, the "engine", the "app framework") and a standard Android Application Project for the contents (that is: an application that actually contains just data). A little bit confusing, just because the "library" here is actually the whole "app", but this seems to be the way to go.
More in detail:
Create an Android Library Application and put into it as much code as you can (all of the non-changing stuff). Please note that this library cannot be launched and cannot be distributed alone. It must be included in a hosting application.
Create a standard Android Application. Include your library into this project. Put in /res and in /asset all of your data (files, XML, etc.).
Compile everything and distribute.
Repeat this cycle every time you need a different version. Different because of data, style, configuration or anything else. Publish the resulting app with a new name.
For what regards me, I'm not completely satisfied by this approach.
A possible alternative is preprocessing the source code with Ruby, Python, Perl, GIT, bash, Ant, Maven, Rake or any other tool that is able to read a file from here, make some change here and there, and write the file there.
The general outline is something like this:
Make a "template" application. Leave your /res and /assset empty.
Run a custom-made script. The script reads a configuration file, copy the /res and /asset files from your repository into the project /res and /asset directories, changes some Java source file and creates/changes some XML file.
Compile and distribute (with a new name, of course).
Using GIT or other SCMs, you just make a new branch for every new version and compile it. Not very elegant (because it can strongly interfere with the normal use of the SCM) but...
There are a few example of these approaches on the web. I'm not completely satisfied by them, either.
Frankly, what the Android ecosystem should offer to solve this problem is some kind of "in-app package manager". Something like the Eclipse Update Manager. This would allow us to use the same application framework to handle different scenarios.
As an alternative, a solid, officially-supported, template-based code-generation mechanism would be nice. Something in the spirit of "Software Production Line": https://en.wikipedia.org/wiki/Software_production_line . Have a look at fw4spl, for example: http://code.google.com/p/fw4spl/ .
The standard advice for sharing code & resources between Android projects is to use a library. Personally I find this works poorly if (a) the shared code changes a lot, or (b) your computer isn't fast enough.
I also don't want to get into deploying multiple APK's, which seems to be necessary when I use dependent projects (i.e. Java Build Path, Projects Tab).
On the other hand, sharing a folder of source code by using the Eclipse linked source feature works great (Java Build Path, Source tab, Link Source button), but for these two issues:
1) I can't use the same technique to share resources. I can create the link to the resources parent folder but then things get wonky and the shared resources don't get compiled (I'm using ADT 21).
2) So then I settle for copying the shared resources into each project, but this doesn't work because either. The shared code can't import the copy of its resources because it doesn't know the package name of the project that uses it. The solution I've been using is to access the resources dynamically, but that has become cumbersome as the number of resources grows.
So, I need a solution to either (1) or (2), or I'll have to go back to a library project. (Or maybe there is another option I haven't thought of?)
Your real problem is (2). Fixing (1) would eliminate some copying, but you would still run into problems with (2).
Unfortunately, that really isn't possible. There's a fair bit of fancy footwork that goes on to make multiple packages possible with library projects, and there's no good way to get that same result without library projects. Anything in res/ of a project is accessed via that project's R class, including your copied resources.
The solution I've been using is to access the resources dynamically
I translated that into you using getIdentifier(). That certainly works. Another approach is to having the hosting app supply resource IDs as parameters to the library code -- this is the pattern that the Android SDK itself uses. This is faster at runtime than the reflection-based getIdentifier(), and it gives the hosting app somewhat more flexibility, but you do wind up adding a bunch of parameters to your methods and constructors as needed to supply the various project-specific R values.