the res/layout* dir of my projects are getting really messy lately and as there are afaik no subdirs allowed there to change that. So it is hard to get structure in there - how do you guys do that?
I don't know about others but for myself I like to use prefixes to help keep things sorted, essentially taking the place of subdirectories. For example, all my activity layouts start with 'activity_' and all my UI controls start with 'control_', notifications with 'notification_', etc.
I am then left with a flat directory with at least some structure, something like:
activity_graph.xml
activity_main.xml
activity_map.xml
control_graph.xml
control_title_bar.xml
notification_just_label.xml
notification_with_progress_bar.xml
...
It's not perfect, but it works for me.
Sorry subfolder inside the layout folder is not possible other than docs specification.
Just check this and this and this question.
Another possibility is to refactor some elements of your application into libraries.
For example you could extract unrelated fragments (as fragments should per se be unrelated) into libraries, mark that project as an Android library (check "Is library" in project properties) and then use your own libraries in your main project.
The resources you need within the separate libs will not collide anymore, but will be "thrown together" at build time, so access is fine.
Here are the docs for that.
Related
I'm having a lot of doubts and after two days of searching I still haven't found a good answer for my problem.
I have an app's project that is already in the store and this project have lots of Activities, Fragments, Services, IntentServices, Layouts, and resources (images, strings, integers, colors, styles, raws, drawables, etc...).
Now, I need to implement a new app that is almost a copy of the first one where I need only to change the background, some resources (but almost 99% stay the same), and maybe in one or two fragments I'll need to change some code (implement different logic statements).
I decided and I think it's natural to convert the all project in an library project.
I did:
1º Create a new project called framework and configured as library. Copied all code and resources (with the exception of assets folder) from the original project to here.
2º In the original project I leave only the manifest, proguard file. I change the manifest and proguard file to reference the classes of the new library.
I tested the app to see if was still working and it was Ok. Until now I did only the separation.
Now, came the problem. I need to create a solution reusable,and scalar for the library that allows me to use it in different apps.
In my original project I created a subclass of Application class that I use for global variables.
Without any others ideas, I decided the following:
1º Convert my MyApplication class in an abstract class. Also, I create an interface ApplicationInterface with some methods like isBackgroundOverlayed() or getBackgroundResource() that I use in the fragments to change the backgrounds or any other logic from the originally defined.
2º In the App's project, I created a new Application class that extends the abstract class MyApplication and implements the interface ApplicationInterface and which is declared in the Application tag in the manifest file.
Conclusion: This all works and I was able to have two app's projects with different background and other images like logos and even change some code logic. An example is in the original App when the user press one certain button, the App shows a dialog choice. In the new app when the user press the button it execute one fragment (without choice).
My concerns: I don't feel this is the best solution for the problem or best practice or good "pattern".
Do you have any ideas?
Thank you in advance!
ps: Sorry if I haven't use this forum properly. I search for an answer but I didn't found any.
I think you have achieved what you wanted, but that was a lengthy and time consuming process. One more thing I would like to mention is you should not change library projects for different applications
As said on Android developers guide :
Library projects contain shareable Android source code and resources that you can reference in Android projects. This is useful when you have common code that you want to reuse.
you can read more from here
Also you have to figure out,which lib is doing which work in case you forget what changes you have made
I would suggest you to keep a separate copy of original project and then import it into new work space in Eclipse (by checking copy project into current work space so that you have a new copy of your project) and consider changing its package name to get a new project
you can refer ans on this link to see how to change package name`
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
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.
I've searched for information about this but it's hard when I don't really know what to search for.
I'm working on a few android projects which share a common base (that I put in a few libs). The libs works with both classes and xml-files, and some other resources too. The most common is that I have a drawable xml which gets color information from an xml-file which defines which colors to use, called something like "foobar_colors.xml" or so. The "foobar_colors.xml" in the lib itself defines default colors.
When I use the lib in the projects these colors needs to change (to use the client company colors or so), and I'm not sure how the best way is to accomplish this... The libs uses allot of resorces, their own xml-layouts and such, so I really can't always "declare things stylable".
The way I do it now is include the "foobar" lib in my project, copy the "foobar_colors.xml" to my project resources and change their values there. This works since R.java seems to "overload" values like the lib itself sets "foobar_color1" to be black and the project sets it again to be red (and the projects defines has higher priority).
Now I'm just wondering, is this safe? Is there any better way to do it? Possible problems that might come up in the future?
My current project is getting awfully large. I have dozens of activities, adapters, fragments, layout xmls, and other resources.
In my (smaller) previous projects I organized stuff with a 1 package / 1 category style. So I had com.stuff.xy.adapter, com.stuff.xy.activity, and so on. Now these packages contain too many items, and I find myself wasting considerable amounts of time searching for a specific class in the package hierarchy.
I use Eclipse, and there are some shortcuts one can use (go to class definition e.g.), but those tend to be situational (I can't use that to quickly jump to a layout definiton xml).
Could you share some tips on organizing large scale projects efficiently? Or some plugins for this perhaps? (It might help for example if I could group together source files that deal with a specific application screen - adapters, layouts, activity and fragment code - so I can quickly open them)
EDIT: After many months developing large projects
First I tried to go with working sets with Eclipse. It didn't really cut it for me, my problem was that our single Android project was simply too big, containing many resources, classes, interfaces, etc. Messing around with working sets in the context of a single project just took too much time, I think that they're mainly useful to organize projects in a single workspace.
On the long run we separated our huge single project into many smaller android-library projects and a single "main application" project that depended on all these smaller ones. This way we could split the resources among these library projects (there were many layouts, values, styles that were only used in certain parts in the application) and code of course. I also created a Base library, that all other libraries depended upon, and contained resources and (base)classes that every part of the application needed.
For all my android projects I prefer to sort code in the following structure:
com.company.projectname is the package of the application.
Underlying packages:
model - all my business-objects
logic - services and objects implementing business logic
screens - all the activities of the project. If activities require adapters and so on, then each activity is placed in a separate package under screens package and the related stuff is placed to the same project.
tools - package with Utility class. SettingsUtil and so on.
In the root of the package I usually have Constants.java interface with constants.
In Eclipse, you can use Working Sets to filter your source/layout/resource files in the Project Explorer view. This is a bit more powerful than packages, since it operates on all files including layout and image assets, not just java source files.
For example, you could create a Home working set which contains HomeActivity.java, HomeAdapter.java, res/layout/home.xml, res/drawable/home_icon.png, etc.
Just another tip.
Use Ctrl-Shift-R to quickly open a resource (you get an autocomplete drop down) and Ctrl-Shift-T to quickly open a java class. The list will also auto-populate using the most recent opened files.
Maybe a tip: to quickly go to a declaration in Eclipse
Hold Ctrl while hovering over a class or method. After 1 sec you get a popup with open declaration / open implementation.
Very useful in large project.
For the rest i recommend just making it intuitive and sort all Activities in a package aswell as all calculations e.g.
for your concern "I can't use that to quickly jump to a layout definiton xml", you can click the name of the layout xml, then ctrl+shift+R will lead you to that definition page.