[AndroidBits] How to decouple navigation between your components

[AndroidBits] How to decouple navigation between your components

The awesome static factory pattern implemented on Android.

November 05, 2016

This article was initially published on   my website, also   available on Medium.


Note: If you are looking for a “How-To” pass data between your Android components, I’ve written a small article explaining.

Decoupled communication

Starting a new activity in Android requires calling startActivity(), you must pass an Intent as a parameter so the framework knows the desired action.

This intent can receive data (as extras) and the associated component class e.g. Activity.

Intent intent = new Intent(this, MyActivity.class);
intent.putExtra("keyFoo", foo);
startActivity(intent);


Looking at the snippet, it’s easy to see the inherent coupling. If for some reason, the initial process/logic of MyActivity changes and requires a change on each instantiation throughout the whole code base, you’re in trouble.

Also, if data needs to be passed both the created, and instantiating classes need a reference to the same key(s) (string) to each intent’s extra, you may end up with a helper/static class with all these key values as a simple solution but, in reality, it’s just unnecessary boilerplate code to maintain for something as simple as changing activities.

Enter the Static Factory Pattern

Static factory methods are simple wrappers that encapsulate what you need to pass when instantiating a new component.

private static final String EXTRA_SOME_TEXT = "someText";
private static final String EXTRA_MY_CUSTOM_OBJECT = "myCustomObject";

public class MyActivity extends AppcompatActivity {
  ...
  // Static factory method  
  public static Intent newStartIntent(Context context, String someText, SomeCustomObject myCustomObject) {
          Intent intent = new Intent(context, MyActivity.class);
          intent.putExtra(EXTRA_SOME_TEXT, someText);
          intent.putExtra(EXTRA_MY_CUSTOM_OBJECT, myCustomObject);
          return intent;
  }
  ...
}
 
  

The example gist shows how you can encapsulate you data in a static context (which means you can call this without having an actual instance) and use this method to instantiate MyActivity. As a bonus you could even make the MyActivity constructor(s) private, this will ensure the factory method is the only way to instantiate.

Now whenever MyActivity needs to be instantiated just call the factory method like this:

// Activity A instantiating "MyActivity"
startActivity(MyActivity.newStartIntent(this, "Hello World", awesomeCustomObject));
 
  

Another cool tip I heard on the Fragmented Podcast (ep. 14) is throwing an exception on that private constructor, if for some odd reason one of your team-mates go around the factory method he will be informed that’s isn’t the intended way to instantiate ??.

private SomeObject() {
  throw new IllegalStateException("You should be using the Static factory method!")
}
 
  

This pattern can be applied to other components, it isn’t specifically for Activities. In fact, the Android fragment has a newInstance() method that follows this same static factory pattern just type “newInstance” on Android Studio and it should pop-up as a suggestion.

That’s it, Happy coding!??


[AndroidBits]: Small articles (bits, get it? ??) discussing simple topics, that I found to be of immense value during my quest to become a better dev!


Would love to talk, feel free to reach out and follow me on   twitter.com/joaquimley

要查看或添加评论,请登录

Joaquim Ley的更多文章

社区洞察

其他会员也浏览了