Web后端开发者应该对依赖注入都比较熟悉,至于Android又是如何进行依赖注入的呢?在这篇文章中,让我们一起通过一个例子了解一下在Android中进行依赖注入的好处。
AndroidAnnotations
AndroidAnnotations是一个致力于加快应用开发速度的Android端开源框架,它关注纵向开发,让开发者把注意义集中在真正重要的事情上。AndroidAnnotations让你的代码变得简单,便于维护。
我们始终应该相信,一个极客应该选择更简单的解决方式,Robert C. Martin说过
读代码和写代码的时间比例是10:1,所以让代码更易读,也会使代码更易编写。
当我们享受沉溺于移动开发的过程时,我们总会问自己,为什么要不断地重复写一些相同的代码?为什么我们的应用越来越难于维护?大量的Context和Activity对象,复杂的线程切换,难于理解的API和各种没必要的广播,我们能不能改善它们呢?
使用
直接使用Java注解就可以让开发者很明确的表现自己的意图,并让AndroidAnnotation在编译时生成中间代码。
特性
- Dependency injection: 可以注入视图、系统服务、资源等内容……
- Simplified threading model: 直接通过注解来决定是在UI线程还是后台执行一个方法。
- Event binding: 通过在方法上添加注解来将事件绑定到视图中,不需要一堆丑陋的匿名监听类。
- REST client: 创建一个客户端接口,AndroidAnnotations就会帮你实现。
- No magic: AndroidAnnotations在编译时会生成子类,你可以查看实现代码。
- AndroidAnnotations提供这些很酷的功能,而且它还不到50kb,而且对性能没有任何的影响
对比
我们可以通过一个简单的例子从代码的角度直观地看一下进行依赖注入前后的区别。
使用前
- public class BookmarksToClipboardActivityextendsActivity {
-
- BookmarkAdapter adapter;
- ListView bookmarkList;
- EditText search;
- BookmarkApplication application;
- Animation fadeIn;
- ClipboardManager clipboardManager;
-
- @Override
- protectedvoid onCreate(Bundle savedInstanceState)super.onCreate(savedInstanceState);
-
- requestWindowFeatureWindowFEATURE_NO_TITLE);
- getWindow().setFlagsFLAG_FULLSCREEN, FLAG_FULLSCREEN);
- setContentViewRlayoutbookmarks);
- bookmarkList =ListView findViewByIdidbookmarkList);
- search EditTextsearch);
- application BookmarkApplication getApplication();
- fadeIn AnimationUtilsloadAnimation(this animfade_in);
- clipboardManager ClipboardManager getSystemServiceCLIPBOARD_SERVICE);
- View updateBookmarksButton1 updateBookmarksButton1);
- updateBookmarksButton1setOnClickListenernewOnClickListener(){
- @Override
- onClick v{
- updateBookmarksClicked();
- }
- });
-
- updateBookmarksButton2 updateBookmarksButton2 updateBookmarksButton2{
- @Override
- ();
- }
- });
-
- setOnItemClickListenerOnItemClickListener{
- onItemClickAdapterView<?> pint poslong idBookmark selectedBookmark BookmarkgetAdaptergetItempos bookmarkListItemClickedselectedBookmark}
- });
- initBookmarkList();
- }
- {
- adapter BookmarkAdapter);
- setAdapteradapter}
- {
- UpdateBookmarksTask task UpdateBookmarksTask();
- taskexecutegetTexttoString(),0); background:transparent">getUserId());
-
- privatestaticfinalString BOOKMARK_URL //
- "http://www.bookmarks.com/bookmarks/{userId}?search={search}";
- AsyncTask<StringVoidBookmarks>{
- @Override
- Bookmarks doInBackground...params searchString [0];
- userId 1];
- RestTemplate client RestTemplateHashMapObject args >();
- argsput("search" searchString"userId" userIdHttpHeaders httpHeaders HttpHeadersHttpEntity request >(httpHeadersResponseEntity response clientexchange//
- BOOKMARK_URLHttpMethodGET request.class bookmarks responsegetBody();
- return bookmarks}
- @Override
- onPostExecute result{
- updateBookmarksresultstartAnimationfadeIn}
- selectedBookmarksetTextgetUrl());
- }
使用后
- @NoTitle
- @Fullscreen
- @EActivity)
-
- @ViewById
- @ViewById
- ;
- @App
- @RestService
- BookmarkClient restClient@AnimationRes
- @SystemService
- @AfterViews
- @Click({ R})
- searchAsync());
- @Background
- getBookmarkssearchString updateBookmarks}
- @UiThread
- {
- @ItemClick
- ());
- }
- }
- @Rest"http://www.bookmarks.com")
- interface@Get"/bookmarks/{userId}?search={search}" getBookmarks}
实践
AndroidAnnotations是如何实现住注入的?我们以@EActivityannotated为例:
- @EActivity
- MyActivity{
- // ...
- }
它会在同一个包下的另一个文件夹中为MyActivity生成了一个子类:
在子类中通过重写为Activity添加实现,比如onCreate()方法,然后在父类中委托,这就是为什么我们使用AndroidAnnotations的时候需要在AndroidManifest.xml中多加一个下划线:
- <activity android:name=".MyListActivity_" />
在开发中,你经常这样启动一个Activity:
startActivityMyListActivity);
然而通过AndroidAnnotations,你必须启动MyListActivity_.class:
MyListActivity_);