Best Practices
Gradle configuration
General structure. Follow Google's guide on Gradle for Android
gradle.properties
KEYSTORE_PASSWORD=password123
KEY_PASSWORD=password789
signingConfigs {
release {
try {
storeFile file("myapp.keystore")
storePassword KEYSTORE_PASSWORD
keyAlias "thekey"
keyPassword KEY_PASSWORD
}
catch (ex) {
throw new InvalidUserDataException("You should define KEYSTORE_PASSWORD and KEY_PASSWORD in gradle.properties.")
}
}
}
Retrolambda
dependencies {
classpath 'me.tatarka:gradle-retrolambda:2.4.+'
}
apply plugin: 'retrolambda'
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
retrolambda {
jdk System.getenv("JAVA8_HOME")
oldJdk System.getenv("JAVA7_HOME")
javaVersion JavaVersion.VERSION_1_7
}
Activities and Fragments
Square even has a library for building architectures mostly with Views,
- Avoid using nested fragments extensively,because matryoshka bugs can occur;
- Avoid putting too much code in activities.
Java packages architecture
com.futurice.project
├─ network
├─ models
├─ managers
├─ utils
├─ fragments
└─ views
├─ adapters
├─ actionbar
├─ widgets
└─ notifications
Resources
Naming:
fragment_contact_details.xml
view_primary_button.xml
activity_main.xml
Organizing layout XMLs.
-
android:id
as the first attribute always -
android:layout_**
attribute at the top -
style
attribute at the bottom - Tag closer
/>
on its own line. - Rather then hard coding
android:text
,using Designtime attributes
Designtime attributes
These are attributes which are used when the layout is rendered in the tool,but have no impact on the runtime.
How to use it
- Add
xmlns:tools="http://schemas.android.com/tools"
to root layout - Use the
tools:
namespace rather than theandroid:
namespace: - In general, you can set any Android framework attribute as a designtime attribute;
Tools Attributes
tools:layout
tools:listitem / listheader / listfooter
tools:showIn Can look the effect in the parent activity_main
tools:menu
Use styles
- Note to accumulate common use Style
- Split a large style file into other files
styles_home.xml
styles_item_details.xml
styles_forms.xml
Colors.xml
colors.xml than just a mapping from a color name to an RGBA value.Names such as "brand_primary", "brand_secondary", "brand_negative" are totally acceptable as well. Formatting colors as such will make it easy to change or refactor colors
- Bad
#FFFFFF
#2A91BD
#5F5F5F
#939393
- Good
#27D34D
#2A91BD
#FF9D2F
#FF432F
Treat dimens.xml like colors.xml.
22sp
18sp
15sp
12sp
40dp
24dp
14dp
10dp
4dp
60dp
40dp
32dp
Strings.xml
- Name your strings with keys that
resemble namespaces
, and don't be afraid of repeating a value for two or more keys. Languages are complex, so namespaces are necessary to bring context and break ambiguity.
Bad
Network error
Call failed
Map loading failed
**Good **
Network error
Call failed
Map loading failed
- Don't write string values in all uppercase.
Bad
CALL FAILED
Good
Call failed
Use
Tag
Beware of problems related to WebViews.
WebViews can also leak memory
public class TestActivity extends Activity {
private FrameLayout mWebContainer;
private WebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
mWebContainer = (FrameLayout) findViewById(R.id.web_container);
mWebView = new WebView(getApplicationContext());
mWebContainer.addView(mWebView);
}
@Override
protected void onDestroy() {
super.onDestroy();
mWebContainer.removeAllViews();
mWebView.destroy();
}
}
Test frameworks
- JUnit tests connectedAndroidTest ,using extension of JUnit with helpers for Android. Follow the official guide [1] [2] for testing.
- Robolectric only for unit tests, not for views.
- Robotium makes writing UI tests easy.
Proguard configuration
ProGuard can cause application crash when thd build command is succeeded :
ClassNotFoundException
, NoSuchFieldException
, similar etc.
**What's you can do **
- See the ProGuard remove
app/build/outputs/proguard/release/usage.txt
- See the ProGuard obfuscated:
app/build/outputs/proguard/release/usage.txt
Common configure
To prevent ProGuard from
- stripping classes or class members,
-keep class com.futurice.project.MyClass { *; }
- obfuscating classes or class members,
-keepnames class com.futurice.project.MyClass { *; }
- Template ,more Proguard Template
Tips.
- Save the mapping.txt ==> when app crash you can see the obuscated stack trace.
Data storage
SharedPreferences
There are two reasons why you might not want to use ShareP
- Data is complex, or a lot of
- Multiple processes accessing the data:
ContentProviders
ContentProviders are fast and process safe. to generate the ContentProvider by using a library such as schematic .
Using an ORM
- Not recommend, unless you have unusually complex data and you have a dire need.
- They tend to be complex and require time to learn.
- whether or not it is process safe if your application requires it