futurice / android-best-practices Goto Github PK
View Code? Open in Web Editor NEWDo's and Don'ts for Android development, by Futurice developers
License: Other
Do's and Don'ts for Android development, by Futurice developers
License: Other
The project template architecture is pretty nice in demonstrating a clean architecture pattern with RxJava.
It would be nice to see more real-world testing examples, as there seems to be a dearth of those. The ones included help ensuring the test framework works, but more flushed out examples would be nice.
You don't have any section speaking about DAO, ORM.
Best Practices, Library (Cupboar/OrmLite/ActiveAndroid/greenDAO/Ollie), ...
The testing section is out of date.
We should update it and address at least the following topics and tools:
TestScheduler
and TestSubscriber
Would be nice to have a section with best practices for using unit testing frameworks (JUnit, Mockito)
Using an event bus is excellent for decoupling communication between Fragments and also between Services and Activities. Possible mechanisms:
I'm guessing the developers of Futurice are obviously aware of the use of event bus but chose not to include it in this list for a reason? If that's the case, I would love to hear an opinion on this.
Hello folks,
I am wondering what is the best practice to handle auto incrementation approach for your builds?
So far I am using approach of generating dynamic version names and code like this:
android {
defaultConfig {
versionName = calculateVersionName()
versionCode = calculateVersionCode()
}
}
ext.calculateVersionName = {}
ext.calculateVersionCode= {}
Inside project, I am storing version.properties
file which is dynamically updated by script.
It basically looks like this:
#Mon Jun 08 11:12:29 UTC 2015
major=2
revision=11
minor=1
patch=0
Basic implementation of calculate methods is following:
Properties retrieveVersionProperties() {
def properties = new Properties()
def stream
try {
stream = new FileInputStream(versionFile)
properties.load(stream)
} catch (java.io.FileNotFoundException ignore) {
} finally {
if (stream != null) stream.close()
}
return properties
}
ext.calculateVersionName = {
def version = retrieveVersionProperties()
// safety defaults in case file missing
if (!version['major']) version['major'] = "1"
if (!version['minor']) version['minor'] = "0"
if (!version['patch']) version['patch'] = "0"
return "${major}.${minor}.${patch}"
}
ext.calculateVersionCode = {
def version = retrieveVersionProperties()
// safety defaults in case file missing
if (!version['revision']) version['revision'] = "1"
def code = 0
code += Integer.valueOf(version['revision'])
return code
}
So if I need to increment build I can simply update my version.properties
file. Though I do not feel like this is the right way to handle auto increment.
Please, can you suggest me something elegant?
Cheers, Tom.
Don't write string values in all uppercase. Stick to normal text conventions (e.g., capitalize first character). If you need to display the string in all caps, then do that using for instance the attribute textAllCaps on a TextView.
I strongly disagree with that. Some devices (e.g. Samsung Galaxy Note 3 SM-N7505) do not really respect textAllCaps
property of TextViews
. So in order to make your app look exactly the same on all devices you SHOULD use string values in all uppercase.
Hi, anyone know if nested ViewPager can be a problem?
I've implemented this on my app and I have a huge increment of performace and non blocking UI, Because it avoid replace or add fragment every time when I need change the content.
I have created a NonSwipeableViewPager and added a normal ViewPager inside it. When the user select a item on NavigationDrawer, the NonSwipeableViewPager slide to position of the content.
Hey,
What do you think about add Android Adapter good practices, such as use BaseAdapter instead of ArrayAdapter or use the ViewHolder pattern?
Check this article: http://www.piwai.info/android-adapter-good-practices/
Thanks for the recopilation!
在实际的项目开发中遇到过使用 x.x.+在编译的时候引入了最新版本。由于新版的改动,而导致项目一些方法调用返回非预期,或者方法被弃用,新版库换了新的实现等一系列的问题。所以后来统一使用指定版本,了解新版特性后在决定要不要升级类库。
使用 Maven 依赖方案代替使用导入jar包方案 如果在你的项目中你明确使用率 jar文件,那么它们可能成为永久的版本,如2.1.1.下载jar包更新他们是很繁琐的, 这个问题Maven很好的解决了,这在Android Gradle构建中也是推荐的方法。你可 以指定版本的一个范围,如2.1.+,然后Maven会自动升级到制定的最新版本,例如:
dependencies {
compile 'com.netflix.rxjava:rxjava-core:0.19.+'
compile 'com.netflix.rxjava:rxjava-android:0.19.+'
compile 'com.fasterxml.jackson.core:jackson-databind:2.4.+'
compile 'com.fasterxml.jackson.core:jackson-core:2.4.+'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.4.+'
compile 'com.squareup.okhttp:okhttp:2.0.+'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.+'
}
Thanks for providing this comprehensive guide.
I think that testing sections should go under a heavy reconsideration.
Android testing support library brings some testing frameworks (like espresso) which changes the way we develop our softwares.
Not to mention special Junit runner for android and Instrumented tests.
Also I think Mockito and Hamcrest libraries should have been mentioned too.
Tnx.
Hi,
I am a web MVC programmer and I developed several projects with Android and Android Studio, i consider the basic architecture as not MVC since Controllers and View are mixed. Separating layout in another file is not enough to make it MVC compliant, because you need some code processing this layout.
This is why for some needs, i created another concept, the LayoutView, this is specific to one layout and allow developer to interact between the controller (Activity/Fragment) and the Template (layout.xml). The layout's LayoutView inherits from an interface (provided by the controller).
This allow multiple layout for one controller depending on usage and allowing reusage through your different apps.
Here is an example for a login form, the known layout are commonly, basic or featured:
public interface LayoutView {
public int getLayoutID();
}
public interface LoginView extends com.another.package.views.LayoutView {
public void reset();
public void setUp();
Credentials getLoginForm();
public void onLoginStart();
public void onLoginEnd();
public void onLoginSuccess();
public void onLoginError();
}
getLayoutID() returns the layout ID \o/
setUp() is called by onCreate() or onCreateView()
reset() is called by onResume()
getLoginForm() is called when clicking Login button, this method extract Credentials from form.
Other method provide a way to show the state of the request to the user (here a Rest API request with Retrofit).
The architecture is
This system is not yet mature.
What do you think about it ?
Thank you very much for the valuable information available here. I have one question thought. Do you know of an obfuscator software (preferably open source) that is able to obfuscate strings inside Android's app class files?
I want to install an Android app on local devices and to write inside the code some credentials for Restful endpoint authentication. I want to make sure that the credentials won't be readable by reverse engineering. Any ideas? Thanks.
Hello,
I would add in Proguard session that for Proguard really optimize the code you should change the line
proguardFiles getDefaultProguardFile('proguard-android.txt'),
to proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
( add -optimize
into the file name), when added it, the release build will take longer bug you'll get a really reduced apk.
Not sure, but looks like the need to add the -optimize
point to optimize file begin in new version of android studio or Proguard.
I had problems my self checking that Proguard was not doing what I was expecting, so I've found it.
Hi, I'm a beginner of Android and translating the doc to Chinese for few days since I noticed that you updated it.
And I found a question when I translated this part https://github.com/futurice/android-best-practices#java-packages-architecture.
I read some articles about the architecture of Android and found that more and more people suggest to use MVP architecture. So I wonder know if the MVC is still the best choice now?
A small problem in readME.The title,Development,not develoment.
I was in the Droidcon a couple of days ago and there was a talk about why not to use Roboelectric. Basically what he said is that it makes the tests slow and when you use it only for unit testing and not for views (what we recommend), doesn't provide anything you could not do yourself.
I don't have experience with Robolectric myself, I never needed it, if my class uses some Bundle or framework related stuff I just wrap it.
So my question: is really a good practice to use Robolectric when it makes your tests slow and it is possible to live without it?
I think it would be good if there were some information regarding to data storing, like:
The new getting started instructions for Robolectric have the details. The template project still uses the plugin.
Add anchor links from the Summary items to their explanation
Can you please explain me the following paragraph in "Activities and Fragments" best practices section:
"Don't abuse Android-level APIs such as heavily relying on Intent for your app's internal workings. You could affect the Android OS or other applications, creating bugs or lag. For instance, it is known that if your app uses Intents for internal communication between your packages, you might incur multi-second lag on user experience if the app was opened just after OS boot."
Thank you in advance
I think there are missing folders eg assets, fonts.
Hello, I wrote a tool that can validate README links (valid URLs, not duplicate). It can be run when someone submits a pull request.
It is currently being used by many projects including
Examples
If you are interested, connect this repo to https://travis-ci.org/ and add a .travis.yml
file to the project.
See https://github.com/dkhamsing/awesome_bot for options, more information
Feel free to leave a comment 😄
Hi everyone.
What do you thing about Android Annotations?
It's a good practice?
I use Activities, Fragments, and custom views, depending on the context. I don't think it's wise to recommend the Fragment approach as a catch-all solution.
Proper screen-to-screen communication. Android's API does not provide a proper way of sending complex data (e.g., some Java Object) from one activity to another activity. With fragments, however, you can use the instance of an activity as a channel of communication between its child fragments.
If you're relying on non-parcelable/serializable POJOs, how do you retain instance state if the user switches to another application? Speaking of that, there's no mention of instance state, parcelable, or serializable in the doc.
Many Android classes expect fragments. The API for tabs on the ActionBar[1] expects the tab contents to be fragments. Also, if using Google Maps API v2, the recommended solution is MapFragment, even though MapView exists.
The ActionBar Tabs API is now deprecated. There's no benefit to use MapFragment over MapView.
Easy to implement swiping transitions between screens. If a UI screen is a fragment in your application, you can use FragmentPagerAdapter to contain a collection of fragments and implement smooth and interactive transitioning between them. For instance, horizontal swiping of screens.
ViewPager has nothing to do with Fragments. It's trivial to implement your own PagerAdapter, the only reason why one is provided in the support lib for fragments is because fragments have such a complex lifecycle.
Also, Fragments don't support some complex transitions. "The Z adjustment only works for window animations. I thought this was documented, but apparently not." This means you can't do things like fade out one fragment and slide in the other from the right, because the outgoing fragment might be rendered above the incoming one.
Intelligent behavior for "back"
The fragment back stack is far from intelligent. You can't remove an item from the back stack unless it's on top, you can't pop the back stack without triggering an animation without hackish workarounds.
I found last commit of Chinese version about 7 month ago and English version update some places from then on.
Wiki from github should be more appropriate to structure your documentation of best practices.
(btw it's help me alot 👍 )
android.app.Fragment
vs android.support.v4.app.Fragment
)?The answer(s) to the above question might make a lot of sense in an android best practices doc?
I would not say using Proguard for your Android application is always a good thing. Main reason why people use Proguard is to strip unused code from your .class files. Why would you do this. Mainly because either 1) You have a bloated library or 2) you have unused code in your own application. Both are scenarios that should be avoided in general, which does not yield into a good reason to use Proguard.
Another reason to use Proguard is obfuscation. But why would use that? For good security you should rely on encryption anyway.
So what's the reasoning for avoiding Proguard? Well, you can spend excess amounts of time tweaking its configuration file when maybe you wouldn't actually need to.
Currently I'm writing a translation of the README.md to portuguese. Could I create a pull request I when finish it?
We currently have the branch templates which is getting ready with one template. As the name suggests, it will be a directory with templates (plural), more than one.
Currently we are making one template based on RxJava, inspired by Timo Tuominen's Rx Android architecture. But since RxJava is not everyone's cup of tea, we should also have templates without it.
There is also the Retrofit vs Volley dichotomy. I can see at least 3 strong and good project templates we should have:
We would some volunteer to guide the way with Volley, because at least I have no experience enough to be able to say "this is how you're supposed to use it".
Hey guys, thanks for the tutorial and general guidelines. Do you have any best practice recommendations wrt providers?
Hello
Espresso (https://code.google.com/p/android-test-kit/) is not mentioned at all. Did you have any bad experience with it?
The guidelines say "avoid using the Guava library, since it contains over 13k methods", as part of the guidance for dealing with the dex method limitation.
While avoiding the method limits is definitely a useful point, I'm pretty suspect of Guava as an issue itself.
For starters, because it's so heavily used in the Android ecosystem already: http://www.appbrain.com/stats/libraries/details/guava/google-guava. It's in 6% of the 500 most downloaded apps, including Spotify, Tumblr, etc.
On top of that, I think Proguard will strip out any methods you don't end up actually using there, so you won't get all 13K methods anyway.
Is there something else I'm missing? It seems like largeish libraries (like Guava) shouldn't actually be an issue, it's more a problem you hit if your app itself grows too large.
Oh, and top of that you should probably put in a note about multi-dex now (or the reasons not to use that I guess, I don't know): http://developer.android.com/tools/building/multidex.html. As of very recently, Google now support building apps with multiple dex files, to solve this issue entirely (and a support library too, to backport that)
Maybe @markvoit or @jonikarppinen or both could share a few sentences about Proguard on the README.md ?
The idea isn't an introduction or tutorial-ish, but really advices coming from battle experiences. That's all what's needed.
Does reusing views/layouts a best practice? I've never done this before. Could anyone please advice on this matter?
I'd love to learn how to reuse my views/layouts or maybe even adapters. For now, I only create new layout for any listviews, gridviews, etc. Just with different file names to distinguish it all.
Edit: Just thought of this. Would it be possible if someone could give advice or tips on creating BaseActivity is a good practice or not, like what to put inside it? (navigation drawer in my mind right now). Perhaps, extending other activities to use this BaseActivity and reusing the same navigation drawer, or other business logic.
Hello. I just have some questions/remarks.
Use Gradle and its recommended project structure
Why not Maven?
Don't write your own HTTP client, use Volley or OkHttp libraries
Aquery, Android Asynchronous Http Client?
Use the Jackson library to parse JSON data
Not GSON?
Do not make a deep hierarchy of ViewGroups
Mb add some links, like this
There are two popular options: the old Ant & Eclipse ADT project structure, and the new Gradle & Android Studio project structure.
Maven & Eclipse?
Always use ProGuard or DexGuard
Shrink? Penny-wise and pound-foolish. Obfuscate? Not sure. Is it always necessary?
Regarding #114, we have been using RESTMock to mock Retrofit calls and it's working like a charm! It uses OkHttp's MockWebServer and it allows to define mock responses for matchers. For instance:
RESTMockServer.whenGET(pathContains("users/defunkt"))
.thenReturnFile(200, "users/defunkt.json");
It also permits to verify if the calls have been done.
Hi, can anyone advise on how to create a good data set to be passed in the Adapter for View creation, like RecyclerView?
For instance, if we want to build a complex RecyclerView layout, how would the data set should look like in JSON. I know it is as simple as passing a Collection with multiple model classes and let the Adapter create the ViewType, but I'd like to know what are the best practices in doing this, scalability and performance wise.
Also, is it a good practice to pass multiple data set into an Adapter?
Thanks
https://github.com/futurice/android-best-practices#gradle-configuration
For this part, when our project needs to be running on Continuous Integration server, which is automatically pulling code from Github, we need to be able to get those fake/dummy
credentials to run the tests.
Is that better if you place all these credentials into Environment Variables
list and export them accordingly when you're in your local machine or running them on CI servers.
Using the package structure outlined in the document, what would be the recommended location for services ?
Its not really part of the view.
Create a pacakge under root called services ?
The project template shows by way of the SubscriptionUtils
class how one could bind data to a TextView.
I'm curious to see how you use this similar approach with list views, adapters and the view model. Do you use the subjects to publish results, and as the results are published, add them as single items to the list adapter?
Alternatively, do you publish a chunk of results for the list, and just set the items on the adapter with one swoop?
Perhaps include this as tip?
Rather than hard coding android:text, consider using design time attributes available for Android studio:
Please include some best practices about naming conventions for android:id
of components in XML layouts.
I am wondering introducing fragments
or adapters
package might ask some classes or methods be unnecessarily public. Could you tell me why you think this packaging is best?
m.futurice.project
├─ network
├─ models
├─ managers
├─ utils
├─ fragments
└─ views
├─ adapters
├─ actionbar
├─ widgets
└─ notifications
For example, if FragmentA takes advantage of an AdapterA and no other fragments do not use the adapter, it might be better they both are in the same package and their methods or classes (if necessary) are declared as package scope. However, if your package architecture is like above, they have to be public.
Do you think there are more classes or methods which would be shared among all the fragments or adapters? Or do you have any other pros for the architecture?
My current opinion is that it would be better to organize classes based on the screens they are related to. Of course, some might be shared among screens (e.g. custom views) but I think there would be less dependencies.
I have been bothering with Java packaging in Android development and I would appreciate if you could tell me some backgrounds behind this best practice.
Thank you.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.