Android library for boilerplate destruction

František Gažo

github.com/FrantisekGazo

slack: @fero.gazo

Problem

public class MyFragment extends Fragment {

    private static final String EXTRA_TEXT = "arg_text";
    private static final String EXTRA_DATA = "arg_data";

    public static MyFragment newInstance(String text, MyData data) {
        MyFragment frag = new MyFragment();
        Bundle args = new Bundle();
        args.putString(EXTRA_TEXT, text);
        args.putParcelable(EXTRA_DATA, data);
        frag.setArguments(args);
        return frag;
    }

    private String mText;
    private MyData mData;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mText = getArguments().getString(EXTRA_TEXT);
        mData = (MyData) getArguments().getParcelable(EXTRA_DATA);
    }
}

new Fragment

  • only default constructor
  • passing data through Bundles
public class MyActivity extends Activity {

    private static final String EXTRA_TEXT = "extra_text";
    private static final String EXTRA_DATA = "arg_data";

    public static Intent newIntent(Contaxt context, String text, MyData data) {
        Intent intent = new Intent(context, MyActivity.class);
        intent.putExtra(EXTRA_TEXT, text);
        intent.putExtra(EXTRA_DATA, data);
        return intent;
    }

    private String mText;
    private MyData mData;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle extras = getIntent().getExtras();
        mText = extras.getString(EXTRA_TEXT);
        mData = (MyData) extras.getParcelable(EXTRA_DATA);
    }
}

new Activity

  • cannot use constructors
  • passing data through Intents
public class MyActivity extends Activity {

    private static final String EXTRA_TEXT = "extra_text";
    private static final String EXTRA_DATA = "arg_data";

    private String mText;
    private MyData mData;

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(EXTRA_DATA, mData);
        outState.putString(EXTRA_TEXT, mText);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        mData = savedInstanceState.getParcelable(EXTRA_DATA);
        mText = (MyData) savedInstanceState.getString(EXTRA_TEXT);
    }   

}

View State

  •  just too much code :)

and more...

Solution?

  • Generates boilerplate code based on used annotations and lets you focus on what matters.
  • Generated code is fully traceable.
  • Everything is generated during compile time.
  • No reflection used!

Available annotations:

public class MyFragment extends Fragment {

    private static final String EXTRA_TEXT = "arg_text";
    private static final String EXTRA_DATA = "arg_data";

    public static MyFragment newInstance(String text, MyData data) {
        MyFragment frag = new MyFragment();
        Bundle args = new Bundle();
        args.putString(EXTRA_TEXT, text);
        args.putParcelable(EXTRA_DATA, data);
        frag.setArguments(args);
        return frag;
    }

    private String mText;
    private MyData mData;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mText = getArguments().getString(EXTRA_TEXT);
        mData = (MyData) getArguments().getParcelable(EXTRA_DATA);
    }
}

new Fragment

public class MyFragment extends Fragment {

    @Arg 
    String mText;
    @Arg 
    MyData mData;

}
  • generates class blade.F
  • 1 method for each Fragment with @Arg:
    • X newX(T1 arg1, ...])
F.newMyFragment("some-string", new MyData());
public class MyActivity extends Activity {

    private static final String EXTRA_TEXT = "extra_text";
    private static final String EXTRA_DATA = "arg_data";

    public static Intent newIntent(Contaxt context, String text, MyData data) {
        Intent intent = new Intent(context, MyActivity.class);
        intent.putExtra(EXTRA_TEXT, text);
        intent.putExtra(EXTRA_DATA, data);
        return intent;
    }

    private String mText;
    private MyData mData;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle extras = getIntent().getExtras();
        mText = extras.getString(EXTRA_TEXT);
        mData = (MyData) extras.getParcelable(EXTRA_DATA);
    }
}

new Activity or Service

public class MyActivity extends Activity {

    @Extra 
    String mText;
    @Extra
    MyData mData;

}
  • generates class blade.I
  • 2 methods for each Activity with @Extra:
    • Intent forX(Context c[, T extra, ...])
    • void startX(Context c[, T extra, ...])
I.startMyActivity(this, "some-string", new MyData());
public class MyActivity extends Activity {

    private static final String EXTRA_TEXT = "extra_text";
    private static final String EXTRA_DATA = "arg_data";

    private String mText;
    private MyData mData;

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(EXTRA_DATA, mData);
        outState.putString(EXTRA_TEXT, mText);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        mData = savedInstanceState.getParcelable(EXTRA_DATA);
        mText = (MyData) savedInstanceState.getString(EXTRA_TEXT);
    }   

}

View State

public class MyActivity extends Activity {

    @State 
    String mText;
    @State
    MyData mData;

}
  • automatically managed: Fragment, Activity, View
@Blade
public class MyActivity extends Activity {
    // no attributes with @Extra
}

@Blade

  • Generates methods even if class doesn't contain @Arg/@Extra

Usage

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0'
        // Add Blade plugin
        classpath 'eu.f3rog.blade:plugin:1.2.0'
    }
}

apply plugin: 'com.android.application'
// Apply Blade plugin
apply plugin: 'blade'

Gradle Plugin

"Just code what is worth coding"

That's all folks

Code

blade

By František Gažo

blade

  • 1,254