2014/10/09 このエントリーをはてなブックマークに追加 はてなブックマーク - 【Android】AndroidAnnotations3.1でジェネリクスが使えなかった話

【Android】AndroidAnnotations3.1でジェネリクスが使えなかった話

カテゴリ:


AndroidAnnotationsより引用




一応、備忘録として。




  • AndroidAnnotationsを使用している
  • AndroidAnnotationsのアノテーションをHogeクラスに付与すると、Hoge_というクラスがジェネレートされる(ビルド時に自動生成)




  • @Transactionalを付与したメソッドの戻り値をList<Map<String, String>にすると、
    ジェネレートされたクラス側でコンパイルエラー

    実際のコードは、以下のような感じ。














        @Transactional
        public List<Map<String, String>> select(SQLiteDatabase db, SQLDomain domain) {
            Cursor c = db.query(domain.getTableName(), ...);
        boolean roop = c.moveToFirst();
        String columnNames[] = c.getColumnNames();
        List<Map<String, String>>resultList = new ArrayList<Map<String, String>>();
        while(roop) {
            Map<String,String> resultMap = new HashMap<String, String>();
            for(String columnName : columnNames) {
                resultMap.put(columnName, c.getString(c.getColumnIndexOrThrow(columnName)));    
            }
            resultList.add(resultMap);
            roop = c.moveToNext();
        }
        c.close();
        return resultList;
    }



    これに対して、ジェネレートされるクラスでは




    import java.util.List<java.util.Map<java.lang.String,java.lang.String>>;
    
    
    
        @Override
        public List<Map<String, String>> select(final SQLiteDatabase db, final SQLDomain domain) {
            db.beginTransaction();
            try {
                String>>result_ = AttendanceManagementDao_.super.select(db, domain);
                db.setTransactionSuccessful();
                return result_;
            } catch (RuntimeException e) {
                Log.e("AttendanceManagementDao_", "Error in transaction", e);
                throw e;
            } finally {
                db.endTransaction();
            }
        }
    


    このような感じ。
    インポート文とローカル変数宣言に失敗している。
    ジェネリクスがらみでとことん失敗してしまうようだ。
    ローカル変数としてジェネリクスを利用する分には問題なさそうなのだが、
    戻り値にList<Map<String, String>>を指定したのが良くなかったぽい。







    アノテーションスコープ(@Transactional)内でジェネリクスを使わない。


    手法としては、2通り思いついた。

    1.List<Map<String, String>を内包するクラスを作る
    2.そもそもジェネリクスを使わない(>_<)


    2は悲しいので、1を採用しました。





    こんな感じ。
    package com.yank.yy.dao;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    
    
    public class DBResult {
    
        
        private List<Map<String,String>> resultList = new ArrayList<Map<String,String>>();
        
        public List<Map<String, String>> get() {
            return resultList;
        }
    
        public void add(Map<String,String> map) {
            resultList.add(map);
        }
    
    }
    









    AndroidAnnotations便利だけど、これに関してはちょっとびっくりした。ていうかウケたw
    ソース解析してコンパイル時にクラスを生成するので、その想定パターン外だったのだろう。
    GoogleさんにIssue出せば直してくれるかな。


    AndroidAnottations、よく考えられている仕組みなので、皆さん使ってみてください。










    0 件のコメント:

    コメントを投稿

    GA