Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Android Development Best
Practices. Android Wear
by Yuriy Voznyak, Software Engineer
eleks.com
You can view the presentation on http://eleksdev.blogspot.com
1
Android Wear
OS for SmartWatches and wearable devices
2
How to pair with?
● Install the Android Wear app
● Tap “Pair with a new watch”
● Tap “Enable Notifications”
Some Wear devices can be
paired with iOS
3
What systems have in common?
Android Wear and Android have common API. Except:
● No WebView in Wear;
● No direct internet connection: use Data Layer API
instead;
● No print subsystem;
● No cloud backup subsystem;
● No application widgets (e.g. on Launchers);
● No interaction with USB devices.
4
How to Show Notifications
Do nothing :) all Push Notifications appear
on Wear. Or customize notifications with
Wear extensions:
5
● User can interact with Wear notifications via Pending
Intent;
● Notifications on Wear can be customized;
● Show only wearable notification, not on handheld;
● Set custom backgrounds.
Distributing Wear apps
When publishing to users, you must package a wearable
app inside of a handheld app, because users cannot
browse and install apps directly on the wearable. If
packaged properly, when users download the handheld
app, the system automatically pushes the wearable app to
the paired wearable.
While developing, installing apps with adb install or
Android Studio directly to the wearable is required.
6
Defining Layouts
Specify Different Layouts for Square and Round Screens
<android.support.wearable.view.WatchViewStub
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/watch_view_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:rectLayout="@layout/rect_activity_wear"
app:roundLayout="@layout/round_activity_wear">
</android.support.wearable.view.WatchViewStub>
7
Accessing layout views
The layouts that you specify for square or round screens are not inflated until WatchViewStub
detects the shape of the screen, so your app cannot access their views immediately. To access
these views, set a listener in your activity to be notified when the shape-specific layout has been
inflated:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wear);
WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override public void onLayoutInflated(WatchViewStub stub) {
TextView tv = (TextView) stub.findViewById(R.id.text); // Now you can access views
...
}
});
}
8
Also You Can
● Design new Watch Faces;
● Work with built-in speakers into
Wearables;
● Debug over Bluetooth;
● Send and collect data via Sync
mechanism;
● … And much much more.
9
Best Practices: Useful Libraries
● Gson;
● EventBus;
● ButterKnife
● Dagger 2
● Glide
● DBFlow
10
GSON
Gson is a Java library used for serializing and deserializing Java objects
from and into JSON. A task you will frequently need to do if you
communicate with APIs. JSON is recommended to use because it’s
lightweight and much simpler than XML.
// Serialize
String userJSON = new Gson().toJson(user);
// Deserialize
User user = new Gson().fromJson(userJSON, User.class);
Gson works great with Retrofit as serializer/deserializer.
See more on https://github.com/google/gson
11
EventBus
EventBus is a library that simplifies communication between different parts of your
application. For example, sending something from an Activity to a running Service,
or easy interaction between fragments.
EventBus is an Android optimized publish/subscribe event bus. A typical use case
for Android apps is gluing Activities, Fragments, and background threads together.
Conventional wiring of those elements often introduces complex and error-prone
dependencies and life cycle issues. With EventBus propagating listeners through all
participants (e.g. background service -> activity -> multiple fragments or helper
classes) becomes deprecated. EventBus decouples event senders and receivers
and thus simplifies communication between app components. Less code, better
quality. And you don't need to implement a single interface!
12
EventBus Example
public class HomeActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this); // register EventBus
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this); // unregister EventBus
}
public void onEventMainThread(NetworkStateChanged event) {
if (!event.isInternetConnected()) {
Toast.makeText(this, "No Internet connection!", Toast.LENGTH_SHORT).show();
}
}
}
public class NetworkStateChanged {}
EventBus.getDefault().post(new NetworkStateChanged());
See more on http://greenrobot.org/eventbus/
13
Butterknife
A library for binding Android views to fields and methods (for instance, binding a view OnClick to a
method). Annotate fields with @Bind and a view ID for Butter Knife to find and automatically cast
the corresponding view in your layout.
class ExampleActivity extends Activity {
@BindView(R.id.title) TextView title;
@BindView(R.id.subtitle) TextView subtitle;
@BindView(R.id.footer) TextView footer;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.bind(this);
// TODO Use fields...
}
}
See more on http://jakewharton.github.io/butterknife/
14
Dagger 2
15
Dagger is a fully static, compile-time dependency injection framework for both Java
and Android. It is an adaptation of an earlier version created by Square and now
maintained by Google. Dagger creates instances of your classes and satisfies their
dependencies. It relies on javax.inject.Inject annotation to identify which constructors
or fields should be treated as dependencies.
Dagger 2 is the successor of the famous Dagger dependency injection library. One of
the major improvements is using zero reflection in generated injection code, which
makes debugging a lot easier.
Dagger 2 is the first to implement the full stack with generated code. The guiding
principle is to generate code that mimics the code that a user might have hand-written
to ensure that dependency injection is as simple, traceable and performant as it can
be.
Dagger Code Example
class Thermosiphon implements Pump {
private final Heater heater;
@Inject
Thermosiphon(Heater heater) {
this.heater = heater;
}
...
}
class CoffeeMaker {
@Inject Heater heater;
@Inject Pump pump;
...
}
16
Also allows to resolve dependencies;
Build the dependencies Graph; Resolve
constructors as Singletons; Lazy
Injections; Compile-time validation and
much much more.
Read more on
http://google.github.io/dagger/
Glide
Glide is the library to use for loading images. Current alternatives are Universal Image Loader
and Picasso.
Glide is recommended by Google.
Here's a simple example how you can use Glide to load an image from a URL into ImageView:
ImageView imageView = (ImageView) findViewById(R.id.my_image_view);
Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView);
See more on https://github.com/bumptech/glide/wiki
17
DBFlow
The Fastest Android ORM Database Library
DBFlow uses Annotation Processing functionality to generate all sorts of classes and
interactions with the database at compile time. This enables the library to run at native speed
and becomes as fast as writing the code yourself. Also, generating code is transparent–we can
see the code that the app executes and catch errors at compile time. Reflection is difficult to
debug, since we will only catch errors at runtime.
List devices = new Select().from(DeviceObject.class)
.where(
Condition.column(DeviceObject$Table.NAME).is("Samsung-Galaxy-S5"),
Condition.column(DeviceObject$Table.CARRIER).is("T-Mobile")).queryList();
Delete.table(DeviceObject.class);
See more on https://github.com/Raizlabs/DBFlow
18
It is only small amount
Think about using libraries!
19
Gradle
● Build different flavours or variants of your app
● Make simple script-like tasks
● Manage and download dependencies
● Customize keystores
● And more
20
Maven Dependencies for Gradle
The main reason is not to keep the library locally as Jar or something else
apply plugin: 'com.android.application'
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
Or
dependencies {
compile 'org.hibernate:hibernate-core:3.6.7.Final'
} 21
IDE
Use Android Studio
Eclipse is deprecated since 2015
22
Components and UI
● Avoid using nested layouts; Avoid deep hierarchy for
views
● Use styles instead of views spot customization;
● Don`t put much code to Activities or Fragments;
● Dont`use Intents for in-application communication. Use
RxJava or EventBus if possible;
● Don`t rely on Android System-level intents.
23
ProGuard
ProGuard is a tool for code obfuscation, shrinking and
optimization
● Use it;
● Verify Release builds for ProGuard rules;
● Keep mapping.txt for every release.
24
Naming Convention
Naming Convention Must Be!
Bad naming convention is better than no convention
25
Useful Links
● https://github.com/futurice/android-best-practices
● https://developer.android.com/guide/practices/index.html
● https://developer.android.com/training/best-performance.html
● https://developer.android.com/training/best-ui.html
● http://www.innofied.com/13-android-development-best-practices/
● https://github.com/ribot/android-
guidelines/blob/master/project_and_code_guidelines.md
● https://google.com
26
It`s Questions Time
Find us at eleks.com Have a question? Write to eleksinfo@eleks.com
27
Inspired by Technology.
Driven by Value.
Find us at eleks.com Have a question? Write to eleksinfo@eleks.com
28

More Related Content

Lecture android best practices

  • 1. Android Development Best Practices. Android Wear by Yuriy Voznyak, Software Engineer eleks.com You can view the presentation on http://eleksdev.blogspot.com 1
  • 2. Android Wear OS for SmartWatches and wearable devices 2
  • 3. How to pair with? ● Install the Android Wear app ● Tap “Pair with a new watch” ● Tap “Enable Notifications” Some Wear devices can be paired with iOS 3
  • 4. What systems have in common? Android Wear and Android have common API. Except: ● No WebView in Wear; ● No direct internet connection: use Data Layer API instead; ● No print subsystem; ● No cloud backup subsystem; ● No application widgets (e.g. on Launchers); ● No interaction with USB devices. 4
  • 5. How to Show Notifications Do nothing :) all Push Notifications appear on Wear. Or customize notifications with Wear extensions: 5 ● User can interact with Wear notifications via Pending Intent; ● Notifications on Wear can be customized; ● Show only wearable notification, not on handheld; ● Set custom backgrounds.
  • 6. Distributing Wear apps When publishing to users, you must package a wearable app inside of a handheld app, because users cannot browse and install apps directly on the wearable. If packaged properly, when users download the handheld app, the system automatically pushes the wearable app to the paired wearable. While developing, installing apps with adb install or Android Studio directly to the wearable is required. 6
  • 7. Defining Layouts Specify Different Layouts for Square and Round Screens <android.support.wearable.view.WatchViewStub xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/watch_view_stub" android:layout_width="match_parent" android:layout_height="match_parent" app:rectLayout="@layout/rect_activity_wear" app:roundLayout="@layout/round_activity_wear"> </android.support.wearable.view.WatchViewStub> 7
  • 8. Accessing layout views The layouts that you specify for square or round screens are not inflated until WatchViewStub detects the shape of the screen, so your app cannot access their views immediately. To access these views, set a listener in your activity to be notified when the shape-specific layout has been inflated: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_wear); WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub); stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() { @Override public void onLayoutInflated(WatchViewStub stub) { TextView tv = (TextView) stub.findViewById(R.id.text); // Now you can access views ... } }); } 8
  • 9. Also You Can ● Design new Watch Faces; ● Work with built-in speakers into Wearables; ● Debug over Bluetooth; ● Send and collect data via Sync mechanism; ● … And much much more. 9
  • 10. Best Practices: Useful Libraries ● Gson; ● EventBus; ● ButterKnife ● Dagger 2 ● Glide ● DBFlow 10
  • 11. GSON Gson is a Java library used for serializing and deserializing Java objects from and into JSON. A task you will frequently need to do if you communicate with APIs. JSON is recommended to use because it’s lightweight and much simpler than XML. // Serialize String userJSON = new Gson().toJson(user); // Deserialize User user = new Gson().fromJson(userJSON, User.class); Gson works great with Retrofit as serializer/deserializer. See more on https://github.com/google/gson 11
  • 12. EventBus EventBus is a library that simplifies communication between different parts of your application. For example, sending something from an Activity to a running Service, or easy interaction between fragments. EventBus is an Android optimized publish/subscribe event bus. A typical use case for Android apps is gluing Activities, Fragments, and background threads together. Conventional wiring of those elements often introduces complex and error-prone dependencies and life cycle issues. With EventBus propagating listeners through all participants (e.g. background service -> activity -> multiple fragments or helper classes) becomes deprecated. EventBus decouples event senders and receivers and thus simplifies communication between app components. Less code, better quality. And you don't need to implement a single interface! 12
  • 13. EventBus Example public class HomeActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EventBus.getDefault().register(this); // register EventBus } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); // unregister EventBus } public void onEventMainThread(NetworkStateChanged event) { if (!event.isInternetConnected()) { Toast.makeText(this, "No Internet connection!", Toast.LENGTH_SHORT).show(); } } } public class NetworkStateChanged {} EventBus.getDefault().post(new NetworkStateChanged()); See more on http://greenrobot.org/eventbus/ 13
  • 14. Butterknife A library for binding Android views to fields and methods (for instance, binding a view OnClick to a method). Annotate fields with @Bind and a view ID for Butter Knife to find and automatically cast the corresponding view in your layout. class ExampleActivity extends Activity { @BindView(R.id.title) TextView title; @BindView(R.id.subtitle) TextView subtitle; @BindView(R.id.footer) TextView footer; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_activity); ButterKnife.bind(this); // TODO Use fields... } } See more on http://jakewharton.github.io/butterknife/ 14
  • 15. Dagger 2 15 Dagger is a fully static, compile-time dependency injection framework for both Java and Android. It is an adaptation of an earlier version created by Square and now maintained by Google. Dagger creates instances of your classes and satisfies their dependencies. It relies on javax.inject.Inject annotation to identify which constructors or fields should be treated as dependencies. Dagger 2 is the successor of the famous Dagger dependency injection library. One of the major improvements is using zero reflection in generated injection code, which makes debugging a lot easier. Dagger 2 is the first to implement the full stack with generated code. The guiding principle is to generate code that mimics the code that a user might have hand-written to ensure that dependency injection is as simple, traceable and performant as it can be.
  • 16. Dagger Code Example class Thermosiphon implements Pump { private final Heater heater; @Inject Thermosiphon(Heater heater) { this.heater = heater; } ... } class CoffeeMaker { @Inject Heater heater; @Inject Pump pump; ... } 16 Also allows to resolve dependencies; Build the dependencies Graph; Resolve constructors as Singletons; Lazy Injections; Compile-time validation and much much more. Read more on http://google.github.io/dagger/
  • 17. Glide Glide is the library to use for loading images. Current alternatives are Universal Image Loader and Picasso. Glide is recommended by Google. Here's a simple example how you can use Glide to load an image from a URL into ImageView: ImageView imageView = (ImageView) findViewById(R.id.my_image_view); Glide.with(this).load("http://goo.gl/gEgYUd").into(imageView); See more on https://github.com/bumptech/glide/wiki 17
  • 18. DBFlow The Fastest Android ORM Database Library DBFlow uses Annotation Processing functionality to generate all sorts of classes and interactions with the database at compile time. This enables the library to run at native speed and becomes as fast as writing the code yourself. Also, generating code is transparent–we can see the code that the app executes and catch errors at compile time. Reflection is difficult to debug, since we will only catch errors at runtime. List devices = new Select().from(DeviceObject.class) .where( Condition.column(DeviceObject$Table.NAME).is("Samsung-Galaxy-S5"), Condition.column(DeviceObject$Table.CARRIER).is("T-Mobile")).queryList(); Delete.table(DeviceObject.class); See more on https://github.com/Raizlabs/DBFlow 18
  • 19. It is only small amount Think about using libraries! 19
  • 20. Gradle ● Build different flavours or variants of your app ● Make simple script-like tasks ● Manage and download dependencies ● Customize keystores ● And more 20
  • 21. Maven Dependencies for Gradle The main reason is not to keep the library locally as Jar or something else apply plugin: 'com.android.application' repositories { mavenCentral() } dependencies { compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final' testCompile group: 'junit', name: 'junit', version: '4.+' } Or dependencies { compile 'org.hibernate:hibernate-core:3.6.7.Final' } 21
  • 22. IDE Use Android Studio Eclipse is deprecated since 2015 22
  • 23. Components and UI ● Avoid using nested layouts; Avoid deep hierarchy for views ● Use styles instead of views spot customization; ● Don`t put much code to Activities or Fragments; ● Dont`use Intents for in-application communication. Use RxJava or EventBus if possible; ● Don`t rely on Android System-level intents. 23
  • 24. ProGuard ProGuard is a tool for code obfuscation, shrinking and optimization ● Use it; ● Verify Release builds for ProGuard rules; ● Keep mapping.txt for every release. 24
  • 25. Naming Convention Naming Convention Must Be! Bad naming convention is better than no convention 25
  • 26. Useful Links ● https://github.com/futurice/android-best-practices ● https://developer.android.com/guide/practices/index.html ● https://developer.android.com/training/best-performance.html ● https://developer.android.com/training/best-ui.html ● http://www.innofied.com/13-android-development-best-practices/ ● https://github.com/ribot/android- guidelines/blob/master/project_and_code_guidelines.md ● https://google.com 26
  • 27. It`s Questions Time Find us at eleks.com Have a question? Write to eleksinfo@eleks.com 27
  • 28. Inspired by Technology. Driven by Value. Find us at eleks.com Have a question? Write to eleksinfo@eleks.com 28