美文网首页
Best Practices

Best Practices

作者: 北疆_ | 来源:发表于2016-04-04 15:53 被阅读39次

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

  1. Add xmlns:tools="http://schemas.android.com/tools" to root layout
  2. Use the tools: namespace rather than the android:namespace:
  3. In general, you can set any Android framework attribute as a designtime attribute;
Tools Attributes

tools:layout

<fragment android:name="com.example.master.ItemListFragment" tools:layout="@android:layout/list_content" />

tools:listitem / listheader / listfooter

<ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@android:layout/simple_list_item_2"
        />

tools:showIn Can look the effect in the parent activity_main

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:text="@string/hello_world"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    tools:showIn="@layout/activity_main" />

tools:menu

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:menu="menu1,menu2" />

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
<resources>
    <color name="button_foreground">#FFFFFF</color>
    <color name="button_background">#2A91BD</color>
    <color name="comment_background_inactive">#5F5F5F</color>
    <color name="comment_background_active">#939393</color>
  • Good
 <!-- basic colors -->
    <color name="green">#27D34D</color>
    <color name="blue">#2A91BD</color>
    <color name="orange">#FF9D2F</color>
    <color name="red">#FF432F</color>

Treat dimens.xml like colors.xml.

<resources>
    <!-- font sizes -->
    <dimen name="font_larger">22sp</dimen>
    <dimen name="font_large">18sp</dimen>
    <dimen name="font_normal">15sp</dimen>
    <dimen name="font_small">12sp</dimen>

    <!-- typical spacing between two views -->
    <dimen name="spacing_huge">40dp</dimen>
    <dimen name="spacing_large">24dp</dimen>
    <dimen name="spacing_normal">14dp</dimen>
    <dimen name="spacing_small">10dp</dimen>
    <dimen name="spacing_tiny">4dp</dimen>

    <!-- typical sizes of views -->
    <dimen name="button_height_tall">60dp</dimen>
    <dimen name="button_height_normal">40dp</dimen>
    <dimen name="button_height_short">32dp</dimen>
</resources>

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
<string name="network_error">Network error</string>
<string name="call_failed">Call failed</string>
<string name="map_failed">Map loading failed</string>

**Good **

<string name="error.message.network">Network error</string>
<string name="error.message.call">Call failed</string>
<string name="error.message.map">Map loading failed</string>
  • Don't write string values in all uppercase.
    Bad
<string name="error.message.call">CALL FAILED</string>

Good

<string name="error.message.call">Call failed</string>

Use <merge>Tag

<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView
        android:id="@+id/imgLoader"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_centerInParent="true"
        android:src="@drawable/ico_loader" />
</merge>

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

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 { *; }

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

相关文章

网友评论

      本文标题:Best Practices

      本文链接:https://www.haomeiwen.com/subject/eooulttx.html