Automat
František Gažo
Android library for boilerplate destruction
10.
Problem
Boilerplate
new Activity
- cannot use constructors
- passing data through Intents
public class NextActivity extends Activity {
private static final String EXTRA_TEXT = "extra_text";
private static final String EXTRA_FLAG = "extra_flag";
public static Intent newIntent(Contaxt context, String text, boolean flag) {
Intent intent = new Intent(context, NextActivity.class);
intent.putExtra(EXTRA_TEXT, text);
intent.putExtra(EXTRA_FLAG, flag);
return intent;
}
}
public class NextActivity extends Activity {
private static final String EXTRA_TEXT = "extra_text";
private static final String EXTRA_FLAG = "extra_flag";
public static Intent newIntent(Contaxt context, String text, boolean flag) {
Intent intent = new Intent(context, NextActivity.class);
intent.putExtra(EXTRA_TEXT, text);
intent.putExtra(EXTRA_FLAG, flag);
return intent;
}
private String mText;
private boolean mFlag;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
mText = extras.getString(EXTRA_TEXT);
mFlag = extras.getBoolean(EXTRA_FLAG);
}
}
new Fragment
- only default constructor
- passing data through Bundles
public class SomeFragment extends Fragment {
private static final String EXTRA_TEXT = "arg_text";
private static final String EXTRA_FLAG = "arg_flag";
public static SomeFragment newInstance(String text, boolean flag) {
SomeFragment frag = new SomeFragment();
Bundle args = new Bundle();
args.putString(EXTRA_TEXT, text);
args.putBoolean(EXTRA_FLAG, flag);
frag.setArguments(args);
return frag;
}
}
public class SomeFragment extends Fragment {
private static final String EXTRA_TEXT = "arg_text";
private static final String EXTRA_FLAG = "arg_flag";
public static SomeFragment newInstance(String text, boolean flag) {
SomeFragment frag = new SomeFragment();
Bundle args = new Bundle();
args.putString(EXTRA_TEXT, text);
args.putBoolean(EXTRA_FLAG, flag);
frag.setArguments(args);
return frag;
}
private String mText;
private boolean mFlag;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mText = getArguments().getString(EXTRA_TEXT);
mFlag = getArguments().getBoolean(EXTRA_FLAG);
}
}
Solution?
APT
- Java Annotation Processor Tool
- can generate code
- cannot modify existing code
- generated code is debuggable
- used library:
ByteCode Weaving
- can modify existing code
- can generate new code
- generated code is not visible
- cannot debug
- used library:
- needs additional Gardle task
- plugin library:
Execution
Annotation Processing
ByteCode Weaving
Result
new Activity
public class NextActivity extends Activity {
@Extra String mText;
@Extra boolean mFlag;
}
public class NextActivity extends Activity {
private static final String EXTRA_TEXT = "extra_text";
private static final String EXTRA_FLAG = "extra_flag";
public static Intent newIntent(Contaxt context, String text, boolean flag) {
Intent intent = new Intent(context, NextActivity.class);
intent.putExtra(EXTRA_TEXT, text);
intent.putExtra(EXTRA_FLAG, flag);
return intent;
}
private String mText;
private boolean mFlag;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
mText = extras.getString(EXTRA_TEXT);
mFlag = extras.getBoolean(EXTRA_FLAG);
}
}
new Activity
- generates class I
- 2 methods for each Activity with @Extra:
- Intent forX(Context c[, T extra, ...])
- void startX(Context c[, T extra, ...])
I.startNextActivity(context, "some text", true);
Intent intent = I.forNextActivity(context, "some text", true);
// set something to intent
startActivity(intent);
public class SomeFragment extends Fragment {
private static final String EXTRA_TEXT = "arg_text";
private static final String EXTRA_FLAG = "arg_flag";
public static SomeFragment newInstance(String text, boolean flag) {
SomeFragment frag = new SomeFragment();
Bundle args = new Bundle();
args.putString(EXTRA_TEXT, text);
args.putBoolean(EXTRA_FLAG, flag);
frag.setArguments(args);
return frag;
}
private String mText;
private boolean mFlag;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mText = getArguments().getString(EXTRA_TEXT);
mFlag = getArguments().getBoolean(EXTRA_FLAG);
}
}
new Fragment
public class SomeFragment extends Fragment {
@Arg String mText;
@Arg boolean mFlag;
}
- generates class F
- 1 method for each Fragment with @Arg:
- Intent newInstance(T extra, ...)
F.newSomeFragment("some text", true);
new Fragment
Use Gradle Plugin
buildscript {
dependencies {
// ...
classpath 'eu.f3rog.automat:plugin:0.2.0'
}
}
apply plugin: 'com.android.application'
apply plugin: 'automat'
Problems
- Only few articles about Bytecode Weaving for Android
- No found examples using both (APT and BW)
- Gradle Plugin - needed modifications
Future
That's all folks :)
Thanks
Open Source:
Automat
By František Gažo
Automat
- 537