Android Annotations概要

6873 ワード

Android Annotations(以下AAという)は開発速度を高めるオープンソースフレームです.Springのように、AAはサンプルコードを減らすことに力を入れています.これは注入に依存して、パッケージの様々な一般的な操作を提供しています.AAを使って、ユーザーは各種の煩雑さを無視して、繰り返しのコード、業務の論理の上で集中します.
AAのコード例を見てみます.
@Fullscreen
@EActivity(R.layout.bookmarks)
@WindowFeature(Window.FEATURE_NO_TITLE)
public class BookmarksToClipboardActivity extends Activity {
  
  BookmarkAdapter adapter;
  
  @ViewById
  ListView bookmarkList;
 
  @ViewById
  EditText search;
  
  @App
  BookmarkApplication application;
  
  @RestService
  BookmarkClient restClient;
 
  @AnimationRes
  Animation fadeIn;
  
  @SystemService
  ClipboardManager clipboardManager;
 
  @AfterViews
  void initBookmarkList() {
    adapter = new BookmarkAdapter(this);
    bookmarkList.setAdapter(adapter);
  }
  
  @Click({R.id.updateBookmarksButton1, R.id.updateBookmarksButton2})
  void updateBookmarksClicked() {
    searchAsync(search.getText().toString(), application.getUserId());
  }
  
  @Background
  void searchAsync(String searchString, String userId) {
    Bookmarks bookmarks = restClient.getBookmarks(searchString, userId);
    updateBookmarks(bookmarks);
  }
 
  @UiThread
  void updateBookmarks(Bookmarks bookmarks) {
    adapter.updateBookmarks(bookmarks);
    bookmarkList.startAnimation(fadeIn);
  }
  
  @ItemClick
  void bookmarkListItemClicked(Bookmark selectedBookmark) {
    clipboardManager.setText(selectedBookmark.getUrl());
  }
 
}
@Rest("http://www.bookmarks.com")
public interface BookmarkClient {
  
  @Get("/bookmarks/{userId}?search={search}")
  Bookmarks getBookmarks(@Path String search, @Path String userId);
 
}
この中でAAのいくつかの機能が示されている.
  • View注入、例えば@ViewById
  • 事件の傍受、例えば@Click@ItemClick
  • スレッド管理、例えば@Background@UiThread
  • は、@SystemService``@RestService
  • のような注入に依存している.
  • Reset Cientは@Get("/bookmarks/{userId}?search={search}")
  • のように生成されます.
    AAを使わないなら、同じ機能でコードを書く必要があります.
    public class BookmarksToClipboardActivity extends Activity {
      
      BookmarkAdapter adapter;
     
      ListView bookmarkList;
     
      EditText search;
     
      BookmarkApplication application;
     
      Animation fadeIn;
     
      ClipboardManager clipboardManager;
     
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN);
     
        setContentView(R.layout.bookmarks);
     
        bookmarkList = (ListView) findViewById(R.id.bookmarkList);
        search = (EditText) findViewById(R.id.search);
        application = (BookmarkApplication) getApplication();
        fadeIn = AnimationUtils.loadAnimation(this, anim.fade_in);
        clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
     
        View updateBookmarksButton1 = findViewById(R.id.updateBookmarksButton1);
        updateBookmarksButton1.setOnClickListener(new OnClickListener() {
     
          @Override
          public void onClick(View v) {
            updateBookmarksClicked();
          }
        });
     
        View updateBookmarksButton2 = findViewById(R.id.updateBookmarksButton2);
        updateBookmarksButton2.setOnClickListener(new OnClickListener() {
     
          @Override
          public void onClick(View v) {
            updateBookmarksClicked();
          }
        });
     
        bookmarkList.setOnItemClickListener(new OnItemClickListener() {
     
          @Override
          public void onItemClick(AdapterView> p, View v, int pos, long id) {
            Bookmark selectedBookmark = (Bookmark) p.getAdapter().getItem(pos);
            bookmarkListItemClicked(selectedBookmark);
          }
        });
     
        initBookmarkList();
      }
     
      void initBookmarkList() {
        adapter = new BookmarkAdapter(this);
        bookmarkList.setAdapter(adapter);
      }
     
      void updateBookmarksClicked() {
        UpdateBookmarksTask task = new UpdateBookmarksTask();
     
        task.execute(search.getText().toString(), application.getUserId());
      }
      
      private static final String BOOKMARK_URL = //
      "http://www.bookmarks.com/bookmarks/{userId}?search={search}";
      
      
      class UpdateBookmarksTask extends AsyncTask {
     
        @Override
        protected Bookmarks doInBackground(String... params) {
          String searchString = params[0];
          String userId = params[1];
     
          RestTemplate client = new RestTemplate();
          HashMap args = new HashMap();
          args.put("search", searchString);
          args.put("userId", userId);
          HttpHeaders httpHeaders = new HttpHeaders();
          HttpEntity request = new HttpEntity(httpHeaders);
          ResponseEntity response = client.exchange( //
              BOOKMARK_URL, HttpMethod.GET, request, Bookmarks.class, args);
          Bookmarks bookmarks = response.getBody();
     
          return bookmarks;
        }
     
        @Override
        protected void onPostExecute(Bookmarks result) {
          adapter.updateBookmarks(result);
          bookmarkList.startAnimation(fadeIn);
        }
        
      }
     
      void bookmarkListItemClicked(Bookmark selectedBookmark) {
        clipboardManager.setText(selectedBookmark.getUrl());
      }
     
    }
    
    ここには非常に多くのサンプルコードが見られます.findViewByIdsetOnClickListener、および匿名内部クラスの煩雑なシンタックス、onItemClick(AdapterView> p, View v, int pos, long id)の煩雑なパラメータ、および無制限なAsyncTaskが含まれています.ネットワーク要求を送信する際の複雑な設定はもちろんです.
    AAは私達のコードを約半分短縮させました.つまりプログラマの半分の体力労働を減少させました.でも、もっと重要なのはコードの可読性を向上させました.最初のコードはAAを使ったことがない開発者でも意味が分かります.これは意味化の様々な注釈のおかげです.
    AAはどうやってこのすべてをやり遂げますか?Springに詳しい開発者の脳にはいくつかの名詞BeanFactoryBeanDefinitionsなどがあるかもしれませんが、AAはSpringとは全く違った方法で依存注入を完了しました.Springは運行時に強化され、AAはコンパイル期間が強化されました.
    AAは標準的なJava Annotation Processing Toolを採用して、コンパイル期間にソースコードを生成します.@EActivityを例にとって、AAはコンパイル期間にこのActivityのサブクラスを生成します.サブクラス名は元のクラス名に下線を付けます.
    package com.some.company;
    @EActivity
    public class MyActivity extends Activity {
      // ...
    }
    
    サブクラスとして生成されます.
    package com.some.company;
    public final class MyActivity_ extends MyActivity {
      // ...
    }
    
    サブクラスの中でマシンが私たちのために作ったサンプルコードです.
    もちろんAAにもハッキリとした欠点があります.侵入性が強すぎるということです.Manifestには必ず加入します.
    
    
    ではなく
    
    
    新しいActivityを起動する時、私達は必ず
    startActivity(this, MyListActivity_.class);
    
    ではなく
    startActivity(this, MyListActivity.class);
    
    あるいはそれの提供するbuilder方法を使用します.
    MyListActivity_.intent(context).start();
    
    このようにもたらしたコードの侵入性は無視できません.特にAAを廃棄すると決めた時、無数のところを変えなければなりません.類名後の下線から脱却できません.SpringのJ 2 EE界での統治地位に比べて、AAは主流の枠組みではありません.これは侵入性が強いと関係があります.