Slide 1

Slide 1 text

Droidcon Berlin

Slide 2

Slide 2 text

Put your Activity on a Diet Guillaume Lung Pedro Lopes

Slide 3

Slide 3 text

[...] @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.container_layout); connectivityListener.registerHandler(connHandler, CONNECTIVITY_MSG); mUnauthoriedRequestReceiver = new UnauthorisedRequestReceiver (getApplicationContext(), getSupportFragmentManager()); setVolumeControlStream(AudioManager.STREAM_MUSIC); registerReceiver(mLoggingOutListener, new IntentFilter(Actions. LOGGING_OUT)); mOnCreateCalled = true; mIsFirstRun = savedInstanceState == null; } [...] Fat activities title, date, 01 of 10

Slide 4

Slide 4 text

Fat activities title, date, 01 of 10 ● Mixture of concerns ● Untested

Slide 5

Slide 5 text

[...] @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.container_layout); networkConnectivityController.onCreate(); unauthorisedRequestController.onCreate(getApplicationContext(), ...); screenStateProvider.onCreate(savedInstanceState); setVolumeControlStream(AudioManager.STREAM_MUSIC); } [...] Separation of concerns title, date, 01 of 10

Slide 6

Slide 6 text

[...] @Test public void isNotForegroundOnPause() { screenStateProvider.onResume(activity); screenStateProvider.onPause(activity); expect(screenStateProvider.isForeground()).toBeFalse(); } [...] Testing the logic title, date, 01 of 10

Slide 7

Slide 7 text

Problems title, date, 01 of 10 ● Boiler plate ● No contract ● Error prone [...] public void onPause() { screenStateProvider.onResume(activity); } [...]

Slide 8

Slide 8 text

Solutions title, date, 01 of 10 ● Application. ActivityLifecycleCallbacks (only API 14+) ● No standard solution yet

Slide 9

Slide 9 text

Solutions title, date, 01 of 10 public class ActivityLightCycleDispatcher { ... } public void add(ActivityLightCycle lightCycle) { ... } public void onCreate(Activity activity, Bundle bundle) { ... } public void onResume(Activity activity) { ... } [...] } public interface ActivityLightCycle { void onCreate(Activity activity, Bundle bundle); void onResume(Activity activity); [...] }

Slide 10

Slide 10 text

public class LightCycleActivity extends Activity implements LightCycleDispatcher { public void attach(ActivityLightCycle lightCycle) { dispatcher.add(lightCycle); } protected void onCreate(Bundle savedInstanceState) { dispatcher.onCreate(this, savedInstanceState); } [...] } Separation of concerns title, date, 01 of 10

Slide 11

Slide 11 text

public class MyActivity extends LightCycleActivity { [...] public MyActivity() { attach(networkConnectivityLightCycle); attach(unauthorisedRequestLightCycle); attach(screenStateLightCycle); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.container_layout); setVolumeControlStream(AudioManager.STREAM_MUSIC); } [...] } Separation of concerns title, date, 01 of 10

Slide 12

Slide 12 text

Apply LightCycle to the code base title, date, 01 of 10 ● All components implement the same interface ● Add tests when extracting ● Hook up light cycles in the base activity

Slide 13

Slide 13 text

There is still some boiler plate. title, date, 01 of 10 public class MyActivity extends LightCycleActivity { [...] public MyActivity() { attach(networkConnectivityLightCycle); attach(unauthorisedRequestLightCycle); attach(screenStateLightCycle); }

Slide 14

Slide 14 text

There is still some boiler plate title, date, 01 of 10 public class MyActivity extends LightCycleActivity { @LightCycle NetworkConnectivityLightCycle networkConnectivityLightCycle; @LightCycle UnauthorisedRequestLightCycle unauthorisedRequestLightCycle; @LightCycle ScreenStateLightCycle screenStateLightCycle; public MyActivity() { LightCycleBinder.bind(this); } [...] }

Slide 15

Slide 15 text

Responsabilities title, date, 01 of 10 ● Activities ○ thin component ○ hook up light cycle components ● LightCycles ○ Do one thing ○ Agnostic to the Activity they are attached to. ○ Independent from the others ○ Platform independant as much as possible ○ Tested

Slide 16

Slide 16 text

More title, date, 01 of 10 ● Works for fragments too ● You can build it if you need it (< 1000 lines). ● Maybe open sourced (TBD)

Slide 17

Slide 17 text

Thanks! Questions ?