Android 的三种依赖注入库, Butter Knife RoboGuice Android Annotation.
Butter Knife 是三者中最简单的一个,它需要加上ButterKnife.inject(this);去执行注入操作,而对于非Activity的组件使用ButterKnife.inject(this,view);来进行注入操作。
class ExampleActivity extends Activity {
@InjectView(R.id.title) TextView title;
@InjectView(R.id.subtitle) TextView subtitle;
@InjectView(R.id.footer) TextView footer;
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.inject(this);
// TODO Use "injected" views...
}
}
public class FancyFragment extends Fragment {
@InjectView(R.id.button1) Button button1;
@InjectView(R.id.button2) Button button2;
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fancy_fragment, container, false);
ButterKnife.inject(this, view);
// TODO Use "injected" views...
return view;
}
}
RoboGuice 是Google的作品,基本能够使用注解的地方都能够支持。view注入,service注入,resource注入都是很简单的但是他的注入需要继承自Robo**组件,例如RoboActivity,RoboService,RoboIntentService,RoboContentProvide.
@ContentView(R.layout.main)
class RoboWay extends RoboActivity {
@InjectView(R.id.name) TextView name;
@InjectView(R.id.thumbnail) ImageView thumbnail;
@InjectResource(R.drawable.icon) Drawable icon;
@InjectResource(R.string.app_name) String myName;
@Inject LocationManager loc;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
name.setText( "Hello, " + myName );
}
}
Android Annotation 的导入很复杂,但是功能很是强大。使用代码如下:
@EActivity(R.layout.my_activity)
public class MyActivity extends Activity {
@ViewById
EditText myEditText;
@ViewById(R.id.myTextView)
TextView textView;
@StringRes(R.string.hello)
String helloFormat;
@ColorRes
int androidColor;
@BooleanRes
boolean someBoolean;
@SystemService
NotificationManager notificationManager;
@SystemService
WindowManager windowManager;
/**
* AndroidAnnotations gracefully handles support for onBackPressed, whether you use ECLAIR (2.0), or pre ECLAIR android version.
*/
public void onBackPressed() {
Toast.makeText(this, "Back key pressed!", Toast.LENGTH_SHORT).show();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// windowManager should not be null
windowManager.getDefaultDisplay();
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
}
@Click
void myButtonClicked() {
String name = myEditText.getText().toString();
setProgressBarIndeterminateVisibility(true);
someBackgroundWork(name, 5);
}
@Background
void someBackgroundWork(String name, long timeToDoSomeLongComputation) {
try {
TimeUnit.SECONDS.sleep(timeToDoSomeLongComputation);
} catch (InterruptedException e) {
}
String message = String.format(helloFormat, name);
updateUi(message, androidColor);
showNotificationsDelayed();
}
@UiThread
void updateUi(String message, int color) {
setProgressBarIndeterminateVisibility(false);
textView.setText(message);
textView.setTextColor(color);
}
@UiThread(delay = 2000)
void showNotificationsDelayed() {
Notification notification = new Notification(R.drawable.icon, "Hello !", 0);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(), 0);
notification.setLatestEventInfo(getApplicationContext(), "My notification", "Hello World!", contentIntent);
notificationManager.notify(1, notification);
}
@LongClick
void startExtraActivity() {
Intent intent = ActivityWithExtra_.intent(this).myDate(new Date()).myMessage("hello !").get();
intent.putExtra(ActivityWithExtra.MY_INT_EXTRA, 42);
startActivity(intent);
}
@Click
void startListActivity(View v) {
startActivity(new Intent(this, MyListActivity_.class));
}
@Touch
void myTextView(MotionEvent event) {
Log.d("MyActivity", "myTextView was touched!");
}
@Transactional
int transactionalMethod(SQLiteDatabase db, int someParam) {
return 42;
}
}
总结:RoboGuice是采用了反射机制实现,更为复杂。而其他两个是在编译时就已经将代码转换好了。AA的功能更为强大,而BufferKnife 使用更为简单。