Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Transfuse

 Transfuse

Overview of the Transfuse framework for Google Android.

John Ericksen

November 06, 2012
Tweet

More Decks by John Ericksen

Other Decks in Programming

Transcript

  1. Typical Android public class BigButtonActivity extends Activity { @Override public

    void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button button = (Button)findViewById(R.id.Button01); button.setOnLongClickListener( new LongClickLogger(button)); } }
  2. Context Base Class • Lifecycle Events • Resource Getters •

    Configuration • Managers • Heavily Associated with View (Activity) • Etc.
  3. Manifest Management <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.apis"> <uses-permission android:name="android.permission.INTERNET" /> <application android:name="ApiDemosApplication">

    <activity android:name="ApiDemos"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
  4. @OnCreate public void logCreated() { Log.i("Created", "Hello World"); } *Any

    Lifecycle Event is available in corresponding injected objects (event different scopes) Lifecycle Events
  5. Lifecycle Events @Activity(label = "Transfuse Example") @Layout(R.id.example_layout) public class Example

    { @OnCreate public void logCreated() { Log.i("Created", "Hello World"); } }
  6. @Inject @Activity(label = "Transfuse Example") @Layout(R.id.example_layout) public class Example {

    @Inject private Dependency1 d1; @Inject public Example(Dependency2 d2){...} @Inject public void setDependency(Dependency3 d3){...} }
  7. Specialty Injections @Inject @View(R.id.button1) Button button; @Inject LocationManager locationManager; @Inject

    Activity activity; @Inject @Preference(value="pref_dialog", defaultValue="test") String dialog; @Inject @Resource(R.string.app_name) String appName;
  8. public class MyParcelable implements Parcelable { private int mData; public

    int describeContents() { return 0; } public void writeToParcel(Parcel out, int flags) { out.writeInt(mData); } public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() { public MyParcelable createFromParcel(Parcel in) { return new MyParcelable(in); } public MyParcelable[] newArray(int size) { return new MyParcelable[size]; } }; private MyParcelable(Parcel in) { mData = in.readInt(); } } Parcelable
  9. @Parcel public class ParcelExample { private String name; private double

    value; public String getName() { return name; } public void setName(String name) { this.name = name; } public double getValue() { return value; } ... @Parcel
  10. @Activity public class ExtraInjection { @Inject @Extra(EXTRA_ONE) private String extraOne;

    @Inject @Extra(value = EXTRA_PARCELABLE, optional=true) private ParcelExample parcelExample; } intentFactory.start( new ExtraInjectionActivityStrategy(TEST_VALUE)); Extras and IntentFactory
  11. @AOPInterceptor public void interceptMe() { } public class InjectedInterceptor implements

    MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) { ... Object retValue = invocation.proceed(); ... return retValue; } } Aspect Oriented Programming
  12. @TransfuseModule @Bind(type = LoopThree.class, to = LoopThreeImpl.class) @BindProvider(type = Random.class,

    provider = RandomProvider.class) @BindInterceptor(annotation = AOPInterceptor.class, interceptor = InterceptorRecorder.class) public class IntegrationModule { @Provides public GenericType<MyType> build(ConcreteType concreteType){ return concreteType; } } Configuration DSL
  13. @Fragment @Layout(R.layout.details) public class DetailFragment { @Inject @View(R.id.detailsText) private TextView

    view; @OnActivityCreated public void onActivityCreated() { Log.i("fragments", "onActivityCreated"); } public void setText(@Observes TextChange textChange) { view.setText(textChange.getValue()); } } @Fragment
  14. @Activity public class ManagedActivity extends Activity { @Override protected void

    onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.display); TextView textView = (TextView) findViewById(R.id.displayText); textView.setText(MANAGED_TEXT); } } Legacy Friendly
  15. Testability? package android.app; public class Activity { public Activity() {

    throw new RuntimeException("Stub!"); } public static long getInstanceCount() { throw new RuntimeException("Stub!"); } public android.content.Intent getIntent() { throw new RuntimeException("Stub!"); } public void setIntent(android.content.Intent newIntent) { throw new RuntimeException("Stub!"); } public final android.app.Application getApplication() { throw new RuntimeException("Stub!"); } public final boolean isChild() { throw new RuntimeException("Stub!"); } public final android.app.Activity getParent() { throw new RuntimeException("Stub!"); } public android.view.WindowManager getWindowManager() { throw new RuntimeException("Stub!"); } public android.view.Window getWindow() { throw new RuntimeException("Stub!"); } public android.view.View getCurrentFocus() { throw new RuntimeException("Stub!"); } public int getWallpaperDesiredMinimumWidth() { throw new RuntimeException("Stub!"); } public int getWallpaperDesiredMinimumHeight() { throw new RuntimeException("Stub!"); } throw new RuntimeException("Stub!"); Android Issues
  16. POJO Components Transfuse Components are Easy to Test @RunWith(RobolectricTestRunner.class) public

    class HelloAndroidTest { private static final String TEST_TEXT = "hello"; private HelloAndroid helloAndroid; private TextView textView; @Before public void setup(){ textView = new TextView(new Activity()); helloAndroid = new HelloAndroid(textView, TEST_TEXT); } @Test public void test(){ helloAndroid.hello(); assertEquals(TEST_TEXT, textView.getText()); } }