Aibolit for android
How tedious is the process of initializing the UI when developing android applications. Over and over again you have to write mountains of template code: findViewbyId, setOnClickListener, getResources (). GetDrawable, ... There is a natural desire to shift this work onto the shoulders of AOP. A quick search for ready-made solutions adapted for android, perhaps only on RoboGuice , which was already mentioned on the hub However, the library has a significant size (~ 0.5 mb), which is unacceptable for many applications, and also requires the inheritance of your application and activity classes from RoboApplication and RoboActivity, which you do not always want to do. That's why Aibolit appeared, lightweight (~ 40kb), easy to use and functional library that uses dependency injection to initialize the UI on android.
We connect the dependency:
and inject
The code is very simple, it is completely relieved of calls to findViewById, setOnClickListener methods and the like. Instead of this:
Call of 2 methods
can be replaced by one:
Aibolit also allows you to inject application application services, as is done in the example above:
You can learn more about this from the documentation for the Aibolit class.
Code sources are open and documented. What is going on behind the scenes? Aibolit analyzes the class for fields and methods marked with Inject * annotations. Each annotation has its own injector class, which is responsible for initializing the field with one or another resource. Below is an example of such an injector responsible for initializing the view:
In order not to give reasons for holivars, I will give just dry numbers. Measurements were made on an emulator. It was necessary to initialize 35 elements (view, licensees, application resources). When using the classical approach, the transition from one activity to another required 40-50 ms, while using aibolit - 90-100 ms. As expected, the reflection-based approach is more time-consuming, but the difference obtained, IMHO, is not significant.
Aibolit can be used both as a finished product, and as a basis for writing your solution. The library code is open and distributed under the Apache License, Version 2.0.
I will be glad to comments and suggestions.
UPD 0:
Similar
roboguice
androidannotations libraries
Opportunities
- view initialization;
- adding event liceners for view;
- initialization of application resources: drawable, string, animation, boolean, dimension, integer, array, color, array adapter;
- initialization of system services;
- initialization of application services of the application.
Usage example
We connect the dependency:
repositories {
maven { url 'https://dl.bintray.com/alexeydanilov/maven' }
}
dependencies {
compile 'com.danikula:aibolit:1.0'
}
and inject
public class AibolitChatActivity extends Activity {
// annotate fields to be injected...
@InjectView(R.id.messageEditText)
private EditText messageEditText;
@InjectView(R.id.historyListView)
private ListView historyListView;
@InjectResource(R.string.symbols_count)
private String symbolsCountPattern;
@InjectSystemService(Context.NOTIFICATION_SERVICE)
private NotificationManager notificationManager;
@InjectService
private HttpManager httpManager;
@InjectResource(R.layout.content)
private View content;
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat_activity);
// initialize annotated fields and methods
Aibolit.doInjections(this);
// or just Aibolit.setInjectedContentView(this);
...
}
// annotate event handlers...
@InjectOnClickListener(R.id.sendButton)
private void onSendButtonClick(View v) {
// handle onClick event
}
@InjectOnClickListener(R.id.clearHistoryButton)
private void onClearHistoryButtonClick(View v) {
// handle onClick event
}
@InjectOnTextChangedListener(R.id.messageEditText)
public void onMessageTextChanged(CharSequence s, int start, int before, int count) {
// handle text changed event
}
...
}
The code is very simple, it is completely relieved of calls to findViewById, setOnClickListener methods and the like. Instead of this:
- we mark view which should be initialized by means of the InjectView annotation;
- we define event handlers and mark them with the corresponding InjectOn * annotations. In this example, event handlers for clicking a button and changing text were defined. Aibolit allows you to add handlers for all major events:
OnClick, OnLongClick, OnTouch, OnKey, OnTextChanged, OnCheckedChange, OnFocusChange, OnItemClick, OnItemSelected, OnEditorAction, OnCreateContextMenu; - We call the method
Aibolit.doInjections(this);
after we set the content for activation.
Call of 2 methods
setContentView(layoutId);
Aibolit.doInjections(this);
can be replaced by one:
Aibolit.setInjectedContentView(this);
Aibolit also allows you to inject application application services, as is done in the example above:
@InjectService
private HttpManager httpManager;
You can learn more about this from the documentation for the Aibolit class.
How it works
Code sources are open and documented. What is going on behind the scenes? Aibolit analyzes the class for fields and methods marked with Inject * annotations. Each annotation has its own injector class, which is responsible for initializing the field with one or another resource. Below is an example of such an injector responsible for initializing the view:
class ViewInjector extends AbstractFieldInjector {
@Override
public void doInjection(Object fieldOwner, InjectionContext injectionContext, Field field, InjectView annotation) {
int viewId = annotation.value();
View view = injectionContext.getRootView().findViewById(viewId);
if (view == null) {
// throw exception...
}
if (!field.getType().isAssignableFrom(view.getClass())) {
// throw exception...
}
try {
field.setAccessible(true);
field.set(fieldOwner, view);
}
catch (IllegalArgumentException e) {
// throw exception...
}
catch (IllegalAccessException e) {
// throw exception...
}
}
}
Performance
In order not to give reasons for holivars, I will give just dry numbers. Measurements were made on an emulator. It was necessary to initialize 35 elements (view, licensees, application resources). When using the classical approach, the transition from one activity to another required 40-50 ms, while using aibolit - 90-100 ms. As expected, the reflection-based approach is more time-consuming, but the difference obtained, IMHO, is not significant.
Aibolit can be used both as a finished product, and as a basis for writing your solution. The library code is open and distributed under the Apache License, Version 2.0.
I will be glad to comments and suggestions.
UPD 0:
Similar
roboguice
androidannotations libraries