├── .gitignore ├── AndroidManifest.xml ├── META-INF └── MANIFEST.MF ├── README.md ├── ant.properties ├── build.gradle ├── build.xml ├── library ├── androidInject_1.0.jar ├── androidInject_1.2.jar └── androidInject_1.3.jar ├── libs ├── android-support-v4.jar ├── gson-2.3.jar └── httpmime-4.2.3.jar ├── proguard-project.txt ├── project.properties ├── res └── values │ └── strings.xml ├── settings.gradle └── src └── com └── wangjie └── androidinject └── annotation ├── annotations ├── base │ ├── AIBean.java │ ├── AIChecked.java │ ├── AIClick.java │ ├── AIFullScreen.java │ ├── AIItemClick.java │ ├── AIItemLongClick.java │ ├── AILayout.java │ ├── AILongClick.java │ ├── AINoTitle.java │ ├── AISystemService.java │ └── AIView.java ├── dimens │ └── AIScreenSize.java ├── mvp │ └── AIPresenter.java ├── net │ ├── AIDelete.java │ ├── AIGet.java │ ├── AIMapper.java │ ├── AINetWorker.java │ ├── AIParam.java │ ├── AIPost.java │ └── AIRaw.java └── orm │ ├── AIColumn.java │ ├── AIPrimaryKey.java │ └── AITable.java ├── cache ├── FieldCache.java ├── MethodCache.java ├── ProcessorCache.java ├── TypeCache.java └── common │ ├── Cacheable.java │ ├── CommonCache.java │ ├── cached │ ├── CachedField.java │ ├── CachedMethod.java │ ├── CachedPresentFields.java │ ├── CachedPresentMethods.java │ └── CachedPresentType.java │ └── generator │ ├── CachedAnnotationProcessorGenerator.java │ ├── CachedGenerator.java │ ├── CachedPresentFieldsGenerator.java │ ├── CachedPresentMethodsGenerator.java │ └── CachedPresentTypeGenerator.java ├── core ├── base │ ├── AnnotationManager.java │ ├── ParticularAnnotation.java │ ├── RealizeAnnotation.java │ ├── RealizeFieldAnnotation.java │ ├── RealizeMethodAnnotation.java │ ├── RealizeTypeAnnotation.java │ └── process │ │ ├── AIAnnotationProcessor.java │ │ ├── field │ │ ├── AIBeanFieldProcessor.java │ │ ├── AINetWorkerFieldProcessor.java │ │ ├── AIPresenterFieldProcessor.java │ │ ├── AIScreenSizeFieldProcessor.java │ │ ├── AISystemServiceFieldProcessor.java │ │ └── AIViewFieldProcessor.java │ │ ├── method │ │ ├── AICheckedMethodProcessor.java │ │ ├── AIClickMethodProcessor.java │ │ ├── AIItemClickMethodProcessor.java │ │ ├── AIItemLongClickMethodProcessor.java │ │ └── AILongClickMethodProcessor.java │ │ └── type │ │ ├── AIFullScreenTypeProcessor.java │ │ ├── AILayoutTypeProcessor.java │ │ └── AINoTitleTypeProcessor.java ├── net │ ├── AINetWork.java │ ├── NetInvoHandler.java │ ├── RetMessage.java │ └── SSLSocketFactoryEx.java └── orm │ ├── AIDatabaseHelper.java │ ├── AIDbExecutor.java │ └── AISqlCase.java ├── exception ├── AIBaseException.java └── AINoSuchAnnotationProcessorException.java ├── listener ├── OnCheckChangedViewListener.java ├── OnClickViewListener.java ├── OnItemClickViewListener.java ├── OnItemLongClickViewListener.java └── OnLongClickViewListener.java ├── present ├── AIActionBarActivity.java ├── AIActivity.java ├── AIAppCompatActivity.java ├── AIFragment.java ├── AIPresent.java ├── AISubLayout.java ├── AISupportFragment.java ├── AISupportFragmentActivity.java └── common │ ├── AnnoProcessorAlias.java │ └── CallbackSample.java └── util ├── AIDbUtil.java ├── AITextUtil.java ├── Params.java └── SystemServiceUtil.java /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Eclipse project files 19 | .classpath 20 | .project 21 | 22 | # Proguard folder generated by Eclipse 23 | proguard/ 24 | 25 | # Intellij project files 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # User define 32 | out/ 33 | proguard_logs/* 34 | 35 | build/ 36 | .gradle/ 37 | 38 | local.properties 39 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | androidInject 2 | ============= 3 | 4 | ###使用注解来简化android开发
(Use annotations inject to simplify the development of android)
5 | 6 | ###注意:
7 | > 重要:需要添加Library[AndroidBucket项目](https://github.com/wangjiegulu/AndroidBucket)的支持(日志、线程、util等) 8 | > 9 | > 使用fragment的注解,需要android-support-v4.jar的支持(以兼容低版本) 10 | > 11 | > 使用网络请求的注解时,如果需要自动返回封装类,则需要[gson.jar](https://code.google.com/p/google-gson/downloads/list)的支持 12 | > 13 | > 使用文件上传的注解,需要[httpmime.jar](http://hc.apache.org/downloads.cgi)的支持 14 | 15 | ###Gadle([Check newest version](http://search.maven.org/#search%7Cga%7C1%7CAndroidInject)) 16 | compile 'com.github.wangjiegulu:AndroidInject:x.x.x' 17 | ###Maven([Check newest version](http://search.maven.org/#search%7Cga%7C1%7CAndroidInject)) 18 | 19 | com.github.wangjiegulu 20 | AndroidInject 21 | x.x.x 22 | 23 | 24 | ###例子1:Android注解
25 | @AIFullScreen 26 | @AINoTitle 27 | @AILayout(R.layout.main) 28 | public class MainActivity extends AIActivity{ 29 | 30 | @AIView(id = R.id.insertBtn, clickMethod = "onClickCallback", longClickMethod = "onLongClickCallback") 31 | private Button insertBtn; 32 | 33 | @AIView(clickMethod = "onClickCallback", longClickMethod = "onLongClickCallback") 34 | private Button queryBtn; 35 | 36 | // @AIView(id = R.id.btn3) 37 | // private Button btn3; 38 | 39 | // @AIView(id = R.id.listView, itemClickMethod = "onItemClickCallback", itemLongClickMethod = "onItemLongClickCallbackForListView") 40 | @AIView(R.id.listView) 41 | private ListView listView; 42 | 43 | @AIBean 44 | private Person person; 45 | 46 | @AISystemService 47 | private AlarmManager alarmManager; 48 | @AISystemService 49 | private LocationManager locationManager; 50 | @AISystemService 51 | private LayoutInflater inflater; 52 | @AIScreenSize 53 | private Point sSize; 54 | @AINetWorker 55 | private PersonWorker personWorker; 56 | 57 | @Override 58 | public void onCreate(Bundle savedInstanceState) { 59 | super.onCreate(savedInstanceState); 60 | List> list = new ArrayList>(); 61 | Map map; 62 | for(int i = 0; i < 10; i++){ 63 | map = new HashMap(); 64 | map.put("title", "item_" + i); 65 | list.add(map); 66 | } 67 | 68 | SimpleAdapter adapter = new SimpleAdapter(context, list, R.layout.list_item, new String[]{"title"}, new int[]{R.id.list_item_title_tv}); 69 | listView.setAdapter(adapter); 70 | 71 | person.setName("wangjie"); 72 | person.setAge(23); 73 | System.out.println(person.toString()); 74 | 75 | System.out.println("alarmManager: " + alarmManager + ", locationManager: " + locationManager + ", inflater: " + inflater); 76 | 77 | System.out.println("screen size --> width: " + sSize.x + ", height: " + sSize.y); 78 | ThreadPool.go(new Runtask() { 79 | @Override 80 | public Object runInBackground() { 81 | try { 82 | // RetMessage retMsg = personWorker.getPersonsForGet("a1", "b1", "c1"); 83 | RetMessage retMsg = personWorker.getPersonsForGet2(new Params().add("aa", "a1").add("bb", "b1").add("cc", "c1")); 84 | 85 | // RetMessage retMsg = personWorker.getPersonsForPost2(new Params().add("aa", "a1").add("bb", "b1").add("cc", "c1")); 86 | System.out.println("getPersonsForGet2: " + retMsg.getList().toString()); 87 | } catch (Exception ex) { 88 | ex.printStackTrace(); 89 | } 90 | return null; 91 | } 92 | }); 93 | 94 | 95 | ThreadPool.go(new Runtask() { 96 | @Override 97 | public Object runInBackground() { 98 | try { 99 | String jsonStr = personWorker.getPersonsForGetToString(new Params().add("aa", "a1").add("bb", "b1").add("cc", "c1")); 100 | System.out.println("getPersonsForGetToString: " + jsonStr); 101 | } catch (Exception e) { 102 | e.printStackTrace(); 103 | } 104 | return null; 105 | } 106 | }); 107 | 108 | 109 | ThreadPool.go(new Runtask() { 110 | @Override 111 | public Object runInBackground() { 112 | try{ 113 | // 上传多个文件 114 | /* 115 | List files = new ArrayList(); 116 | files.add(new File("/storage/emulated/0/DCIM/Camera/20140130_132710.jpg")); 117 | files.add(new File("/storage/emulated/0/DCIM/Camera/20140130_132559.jpg")); 118 | files.add(new File("/storage/emulated/0/DCIM/Camera/20140130_132533.jpg")); 119 | files.add(new File("/storage/emulated/0/DCIM/Camera/20140130_132508.jpg")); 120 | RetMessage retMsg = personWorker.uploadFile(files); 121 | System.out.println(retMsg.getList().toString()); 122 | */ 123 | // 上传单个文件 124 | RetMessage retMsg = personWorker.uploadFile2(new File("/storage/emulated/0/DCIM/Camera/20140130_132710.jpg")); 125 | System.out.println(retMsg.getList().toString()); 126 | 127 | }catch(Exception ex){ 128 | ex.printStackTrace(); 129 | } 130 | return null; 131 | } 132 | }); 133 | 134 | 135 | 136 | userExecutor = new DbExecutor(context); 137 | } 138 | 139 | DbExecutor userExecutor = null; 140 | User dbUser = null; 141 | List users = null; 142 | Random rd = new Random(); 143 | @AIClick({R.id.deletebtn, R.id.updateBtn}) 144 | public void onClickCallback(View view) throws Exception{ 145 | if(view instanceof Button){ 146 | Toast.makeText(context, "onClickCallback: " + ((Button)view).getText(), Toast.LENGTH_SHORT).show(); 147 | } 148 | switch(view.getId()){ 149 | case R.id.insertBtn: // 插入user对象到user表 150 | dbUser = new User("wangjie" + rd.nextInt(10000), String.valueOf(rd.nextInt(10000) + 10000), System.currentTimeMillis(), rd.nextInt(80) + 120, rd.nextInt(80) + 120, "aaaa"); 151 | userExecutor.executeSave(dbUser); 152 | break; 153 | 154 | case R.id.queryBtn: // 查询user表 155 | users = userExecutor.executeQuery("select * from user where uid > ?", new String[]{"4"}, User.class); 156 | System.out.println("[queryBtn]users: " + users); 157 | break; 158 | 159 | case R.id.deletebtn: // 删除user表的一条数据 160 | if(null == users || users.size() <= 0){ 161 | break; 162 | } 163 | userExecutor.executeDelete(users.get(0)); 164 | break; 165 | 166 | case R.id.updateBtn: // 更新user表的一条数据 167 | if(null == users || users.size() <= 0){ 168 | break; 169 | } 170 | User user = users.get(0); 171 | user.setUsername(user.getUsername().startsWith("wangjie") ? "jiewang" + rd.nextInt(10000) : "wangjie" + rd.nextInt(10000)); 172 | user.setPassword(user.getPassword().startsWith("123456") ? "abcdef" : "123456"); 173 | user.setCreatemillis(System.currentTimeMillis()); 174 | user.setHeight(rd.nextInt(80) + 120); 175 | user.setWeight(rd.nextInt(80) + 120); 176 | user.setNotCol("bbb"); 177 | userExecutor.executeUpdate(user, null, new String[]{"createmillis"}); 178 | break; 179 | 180 | } 181 | 182 | } 183 | 184 | public void onLongClickCallback(View view){ 185 | if(view instanceof Button){ 186 | Toast.makeText(context, "onLongClickCallback: " + ((Button)view).getText(), Toast.LENGTH_SHORT).show(); 187 | } 188 | } 189 | 190 | public void onItemClickCallback(AdapterView adapterView, View view, int i, long l) { 191 | Toast.makeText(context, "onItemClickCallback: " + ((Map)adapterView.getAdapter().getItem(i)).get("title"), Toast.LENGTH_SHORT).show(); 192 | } 193 | 194 | @AIClick({R.id.toFragmentBtn}) 195 | public void onClickCallbackForBtn3(View view){ 196 | if(view instanceof Button){ 197 | Toast.makeText(context, "onClickForUpdateBtn: " + ((Button)view).getText(), Toast.LENGTH_SHORT).show(); 198 | } 199 | 200 | if(view.getId() == R.id.toFragmentBtn){ 201 | startActivity(new Intent(context, SecendActivity.class)); 202 | } 203 | 204 | 205 | } 206 | 207 | @AILongClick({R.id.updateBtn}) 208 | public void onLongClickCallbackForBtn3(View view){ 209 | if(view instanceof Button){ 210 | Toast.makeText(context, "onLongClickCallbackForBtn3: " + ((Button)view).getText(), Toast.LENGTH_SHORT).show(); 211 | } 212 | } 213 | 214 | @AIItemClick({R.id.listView}) 215 | public void onItemClickCallbackForListView(AdapterView adapterView, View view, int i, long l){ 216 | Toast.makeText(context, "onItemClickCallbackForListView: " + ((Map)adapterView.getAdapter().getItem(i)).get("title"), Toast.LENGTH_SHORT).show(); 217 | } 218 | 219 | @AIItemLongClick(R.id.listView) 220 | public boolean onItemLongClickCallbackForListView(AdapterView adapterView, View view, int i, long l) { 221 | Toast.makeText(context, "onItemLongClickCallbackForListView: " + ((Map)adapterView.getAdapter().getItem(i)).get("title"), Toast.LENGTH_SHORT).show(); 222 | return true; 223 | } 224 | 225 | 226 | 227 | } 228 | 229 | 230 | 231 | ###例子2:网络请求注解
232 | @AIMapper("http://192.168.2.198:8080/HelloSpringMVC") 233 | public interface PersonWorker { 234 | @AIGet("/person/findPersons?aa=#{a3}&bb=#{b3}&cc=#{c3}") 235 | public RetMessage getPersonsForGet(@AIParam("a3")String a2, @AIParam("b3") String b2, @AIParam("c3") String c2) throws Exception; 236 | 237 | @AIPost("/person/findPersons") 238 | public RetMessage getPersonsForPost(@AIParam("aa")String a2, @AIParam("bb") String b2, @AIParam("cc") String c2) throws Exception; 239 | 240 | @AIGet(value = "/person/findPersons", connTimeout = 12345, soTimeout = 54321) 241 | public RetMessage getPersonsForGet2(Params params) throws Exception; 242 | 243 | @AIPost(value = "/person/findPersons", connTimeout = 30000, soTimeout = 25000) 244 | public RetMessage getPersonsForPost2(Params params) throws Exception; 245 | 246 | @AIUpload("/upload/uploadFiles") 247 | public RetMessage uploadFile(List files) throws Exception; 248 | 249 | @AIUpload("/upload/uploadFiles") 250 | public RetMessage uploadFile2(File file) throws Exception; 251 | 252 | @AIGet(value = "/person/findPersons", connTimeout = 12345, soTimeout = 54321) 253 | public String getPersonsForGetToString(Params params) throws Exception; 254 | 255 | } 256 | 257 | ###例子3:数据表映射注解
258 | @AITable 259 | public class User implements Serializable{ 260 | @AIColumn 261 | @AIPrimaryKey(insertable = false) 262 | private int uid; 263 | @AIColumn("username") 264 | private String username; 265 | @AIColumn 266 | private String password; 267 | @AIColumn 268 | private long createmillis; 269 | @AIColumn 270 | private float height; 271 | @AIColumn 272 | private double weight; 273 | 274 | private String notCol; 275 | 276 | public User() { 277 | } 278 | 279 | public User(String username, String password, long createmillis, float height, double weight, String notCol) { 280 | this.username = username; 281 | this.password = password; 282 | this.createmillis = createmillis; 283 | this.height = height; 284 | this.weight = weight; 285 | this.notCol = notCol; 286 | } 287 | // ... getter/setter 288 | } 289 | 290 | 291 | ###可用注解(Annotations):
292 | ### 293 | @AINoTitle: 类注解, 只适用于Activity(需继承于AIActivity), 设置Activity不显示Title 294 | 295 | @AIFullScreen: 类注解, 只适用于Activity(需继承于AIActivity), 设置Activity全屏 296 | 297 | @AILayout: 类注解 298 | value[int]: 用于设置该Activity的布局 ---- setContentView(resId); 299 | 300 | 301 | @AIView: 属性注解 302 | value[int]: 用于绑定控件 ---- findViewById(resId);(default identifier[R.id.{field name}] if did not set id) 303 | id[int]: 同value,如果两个都设置,则使用value值 304 | clickMethod[String]: 用于设置控件点击事件的回调方法, 可选, 方法名称任意, 参数必须为(View view) 305 | longClickMethod[String]: 用于设置控件长按的回调方法, 可选, 方法名任意, 参数必须为(View view) 306 | itemClickMethod[String]: 用于设置控件item点击的回调方法, 可选, 方法名任意, 参数必须为(AdapterView, View, int, long) 307 | itemLongClickMethod[String]: 用于设置控件item长按的回调方法, 可选, 方法名任意, 参数必须为(AdapterView, View, int, long) 308 | 309 | @AIBean: 属性注解, 为该属性生成一个对象并注入, 该对象必须有个默认的不带参数的构造方法 310 | 311 | @AISystemService: 属性注解,为该属性注入系统服务对象 312 | 313 | 314 | @AIClick: 方法注解 315 | value[int[], 所要绑定控件的id]: 用于绑定控件点击事件的回调方法, 方法名称任意, 参数必须为(View view) 316 | 317 | @AIItemClick: 方法注解 318 | value[int[], 所要绑定控件的id]: 用于绑定控件item点击事件的回调方法, 方法名称任意, 参数必须为(AdapterView, View, int, long) 319 | 320 | @AILongClick: 方法注解 321 | value[int[], 所要绑定控件的id]: 用于绑定控件长按事件的回调方法, 方法名称任意, 参数必须为(View view) 322 | 323 | @AIItemLongClick: 方法注解 324 | value[int[], 所要绑定控件的id]: 用于绑定控件item长按事件的回调方法, 方法名称任意, 参数必须为(AdapterView, View, int, long) 325 | 326 | @AIScreenSize: 属性注解 327 | 用于注入当前设备的屏幕大小(宽高) 328 | 329 | @AIMapper:类注解,使用在NetWorker接口上面 330 | value:value值可以自动拼接在该接口中声明的方法url上面 331 | 332 | @AIGet: 方法注解 333 | value[String, 所要请求的url]:表示以GET来请求url 334 | connTimeout[int, 连接超时时间]:连接一个url的连接等待时间 335 | soTimeout[int, response返回超时时间]:连接上一个url,获取response的返回等待时间 336 | 337 | @AIPost: 方法注解 338 | value[String, 所要请求的url]:表示以Post来请求url 339 | connTimeout[int, 连接超时时间]:连接一个url的连接等待时间 340 | soTimeout[int, response返回超时时间]:连接上一个url,获取response的返回等待时间 341 | 342 | @AIParam: 方法参数注解 343 | value[String, 请求的参数别名]:注入@AIGet或@AIPost注解方法的请求参数 344 | 345 | @AINetWorker: 属性注解 346 | 注入网络请求服务 347 | 348 | @AIUpload: 方法注解,用于上传文件到服务器(支持多文件上传) 349 | value[String, 所要请求的url]:表示要上传的url,默认用post请求(不需要使用@AIPost注解) 350 | connTimeout[int, 连接超时时间]:连接一个url的连接等待时间 351 | soTimeout[int, response返回超时时间]:连接上一个url,获取response的返回等待时间 352 | 注意:使用此注解的方法参数需要包含Collection或其子类型集合 或者包含File对象 来作为要上传的文件 353 | 354 | @AIColumn: 属性注解,用于映射属性到表字段 355 | value[String]:表示要映射到的表字段名称,不填写则默认以属性名作为表字段名 356 | 357 | @AIPrimaryKey: 属性注解,用于指定属性为主键 358 | insertable[boolean]:表示插入数据时是否同时也插入主键到表。默认为false,即表的主键应该为自动生成 359 | 360 | @AITable: 类注解,用于映射类到表 361 | value[String]: 表示要映射到的表的名称,不填写或未增加该注解则默认以类名小写为表名 362 | 363 | @AIPresenter:属性注解,使用MVP时使用,该注解用于在Activity上注入Presenter,自动在Presenter中注入Viewer和Interactor对象 364 | 365 | 366 | 367 | ###提交日志(Commit Logs):
368 | ### 369 | 2014-7-18: 370 | 1. 新增@AIPresenter注解,使用MVP时使用,该注解用于在Activity上注入Presenter,自动在Presenter中注入Viewer和Interactor对象 371 | 372 | 2014-4-15: 373 | 1. 新增@AIMapper注解,该注解使用在NetWorker接口上面,value值可以自动拼接在该接口中声明的方法url上面 374 | 375 | 2014-4-13: 376 | 1. 解决Gson所引发的bug 377 | 378 | 2014-3-27: 379 | 1. 去除线程池,转移到AndroidBucket项目中,所以需要添加Library[AndroidBucket项目](https://github.com/wangjiegulu/AndroidBucket)的支持(日志、线程、util等) 380 | 2. 修改Gson DateFormat为yyyy-MM-dd HH:mm:ss:SSS 381 | 382 | 2014-3-25: 383 | 1. 增加线程池的配置 384 | 385 | 2014-3-25: 386 | 1. AIDbExecutor增加使用事务执行多条sql 387 | 388 | 2014-3-25: 389 | 1. 增加对sqlite3数据库的orm注解支持,增加@AIColumn、@AIPrimaryKey、@AITable三个注解来映射到表(有待改进) 390 | 2. 重构代码 391 | 392 | 2014-3-24: 393 | 1. build androidInject_1.3.jar 394 | 395 | 2014-3-11: 396 | 1. netWorker中方法申明的返回类型为String时,则直接返回请求体的String 397 | 398 | 2014-2-26: 399 | 1. 修改@AIView注解的value和id值均代表控件redId,简化注入AIView代码,如:@AIView(R.id.listView),如果两个都设置,则使用value值 400 | 2. 增加AIActivity、AISupportFragment、AISupportFragmentActivity解析Annotations时间统计,打印log 401 | 402 | 2014-2-10: 403 | 1. 增加文件上传注解@AIUpload 404 | 2. 代码重构 405 | 406 | 2014-2-10: 407 | 1. @AIGet和@AIPost增加connTimeout(连接一个url的连接等待时间)和soTimeout设置(连接上一个url,获取response的返回等待时间) 408 | 409 | 2014-2-10: 410 | 1. Worker中添加异常抛出 411 | 412 | 2014-2-8: 413 | 1. 增加GET或POST请求时请求参数可使用Params类传入,简化代码 414 | 415 | 2014-2-8: 416 | 1. 增加@AIScreenSize注解,作用于属性,用于注入当前设备的屏幕大小(宽高) 417 | 2. 增加对网络请求的支持,使用动态代理实现:@AIGet注解,作用于接口方法,表示以GET来请求url;@AIPost注解,作用于接口方法,表示以POST来请求url;@AIParam,用于注入请求参数 418 | 3. 增加@AINetWorker注解,作用于属性,用于注入网络请求服务 419 | 4. 重构代码 420 | 421 | 2013-12-17: 422 | 1. refactor source 423 | 424 | 2013-12-5: 425 | 1. build androidInject_1.0.jar 426 | 427 | 2013-12-5: 428 | 1. add fragment support(need android-support-v4.jar) 429 | 430 | 2013-12-4: 431 | 1. add typeList annotations: @AINoTitle, @AIFullScreen 432 | 2. modify field annotation ---- @AIView: default identifier[R.id.{field name}] if did not set id 433 | 434 | 2013-12-2: 435 | 1. add field annotations: @AIBean, @AISystemService 436 | 437 | 2013-12-1: 438 | 1. add method annotations: @AIItemLongClick 439 | 2. add annotations(itemLongClickMethod) of @AIView 440 | 441 | 2013-12-1: 442 | 1. RENAME @InitLayout, @InitView TO @AILayout, @AIView 443 | 2. ADD method annotations: @AIClick, @AILongClick, @AIItemClick 444 | 3. refactor source 445 | 446 | 447 | License 448 | ======= 449 | 450 | Copyright 2013 Wang Jie 451 | 452 | Licensed under the Apache License, Version 2.0 (the "License"); 453 | you may not use this file except in compliance with the License. 454 | You may obtain a copy of the License at 455 | 456 | http://www.apache.org/licenses/LICENSE-2.0 457 | 458 | Unless required by applicable law or agreed to in writing, software 459 | distributed under the License is distributed on an "AS IS" BASIS, 460 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 461 | See the License for the specific language governing blacklist and 462 | limitations under the License. 463 | 464 | 465 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-androidInject-brightgreen.svg?style=flat)](http://android-arsenal.com/details/1/1581) 466 | 467 | -------------------------------------------------------------------------------- /ant.properties: -------------------------------------------------------------------------------- 1 | # This file is used to override default values used by the Ant build system. 2 | # 3 | # This file must be checked into Version Control Systems, as it is 4 | # integral to the build system of your project. 5 | 6 | # This file is only used by the Ant script. 7 | 8 | # You can use this to override default values such as 9 | # 'source.dir' for the location of your java source folder and 10 | # 'out.dir' for the location of your output folder. 11 | 12 | # You can also use it define how the release builds are signed by declaring 13 | # the following properties: 14 | # 'key.store' for the location of your keystore and 15 | # 'key.alias' for the name of the key to use. 16 | # The password will be asked during the build when you use the 'release' target. 17 | 18 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() //你所使用的仓库 4 | } 5 | dependencies { 6 | classpath 'com.android.tools.build:gradle:1.1.1' // Gradle 的Android 插件版本 7 | } 8 | } 9 | apply plugin: 'com.android.library' // 导入Android Application 插件,将此module 配置成application module 10 | 11 | repositories { 12 | jcenter() // 仓库 13 | } 14 | 15 | android { 16 | 17 | compileSdkVersion 22 // 使用SDK的版本,请配置你SDK中有的最新版本 18 | buildToolsVersion "22.0.1" // buildTools 版本,你SDK中有哪个版本配哪个版本,建议更新到最新的版本 19 | 20 | 21 | defaultConfig { 22 | minSdkVersion 9 23 | targetSdkVersion 22 24 | versionCode 5 25 | versionName "1.0.6" 26 | } 27 | 28 | buildTypes { // 配置打包的版本 29 | release { // 发行版 30 | minifyEnabled false // 是否混淆 31 | // proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt' // 默认混淆文件 32 | // proguardFiles 'proguard-project.txt' // 自定义混淆文件 33 | } 34 | debug { // debug 版 35 | 36 | } 37 | } 38 | 39 | sourceSets { // 如果你的工程是从ANT 中迁移过来,可以使用sourceSets 来配置工程结构,如果你使用的是标准Gradle 结构,可以不需要配置。 40 | main { 41 | java.srcDirs = ['src'] 42 | aidl.srcDirs = ['src'] 43 | renderscript.srcDirs = ['src'] 44 | res.srcDirs = ['res'] 45 | assets.srcDirs = ['assets'] 46 | jniLibs.srcDirs = ['libs'] // 配置此处才会打包jni 的.so 文件 47 | jni.srcDirs=['jni'] 48 | manifest.srcFile 'AndroidManifest.xml' 49 | } 50 | } 51 | 52 | packagingOptions { 53 | exclude 'META-INF/DEPENDENCIES.txt' 54 | exclude 'META-INF/LICENSE.txt' 55 | exclude 'META-INF/NOTICE.txt' 56 | exclude 'META-INF/NOTICE' 57 | exclude 'META-INF/LICENSE' 58 | exclude 'META-INF/DEPENDENCIES' 59 | exclude 'META-INF/notice.txt' 60 | exclude 'META-INF/MANIFEST.MF' 61 | exclude 'META-INF/license.txt' 62 | exclude 'META-INF/dependencies.txt' 63 | } 64 | 65 | lintOptions { 66 | checkReleaseBuilds false 67 | // Or, if you prefer, you can continue to check for errors in release builds, 68 | // but continue the build even when errors are found: 69 | abortOnError false 70 | } 71 | 72 | } 73 | 74 | /** 75 | * https://gradle.org/docs/current/dsl/org.gradle.api.artifacts.dsl.DependencyHandler.html 76 | */ 77 | dependencies { 78 | // compile fileTree(dir: 'libs', include: ['*.jar']) 79 | // compile 'com.github.wangjiegulu:AndroidBucket:1.0.1' 80 | 81 | // compile 'com.android.support:support-v4:21.0.3' 82 | compile 'com.google.code.gson:gson:2.3.1' 83 | compile 'org.apache.httpcomponents:httpmime:4.3.6' 84 | compile project(":AndroidBucket"); 85 | 86 | 87 | } -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 49 | 50 | 51 | 52 | 56 | 57 | 69 | 70 | 71 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /library/androidInject_1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjiegulu/androidInject/20aa0a5eb561bdbd31c5f1bb1e4b555b11e976ff/library/androidInject_1.0.jar -------------------------------------------------------------------------------- /library/androidInject_1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjiegulu/androidInject/20aa0a5eb561bdbd31c5f1bb1e4b555b11e976ff/library/androidInject_1.2.jar -------------------------------------------------------------------------------- /library/androidInject_1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjiegulu/androidInject/20aa0a5eb561bdbd31c5f1bb1e4b555b11e976ff/library/androidInject_1.3.jar -------------------------------------------------------------------------------- /libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjiegulu/androidInject/20aa0a5eb561bdbd31c5f1bb1e4b555b11e976ff/libs/android-support-v4.jar -------------------------------------------------------------------------------- /libs/gson-2.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjiegulu/androidInject/20aa0a5eb561bdbd31c5f1bb1e4b555b11e976ff/libs/gson-2.3.jar -------------------------------------------------------------------------------- /libs/httpmime-4.2.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjiegulu/androidInject/20aa0a5eb561bdbd31c5f1bb1e4b555b11e976ff/libs/httpmime-4.2.3.jar -------------------------------------------------------------------------------- /proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep optionViewModels here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-21 15 | android.library=true 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':AndroidBucket' 2 | 3 | //Properties props = new Properties() 4 | //props.load(new FileInputStream("local.properties")) 5 | project(":AndroidBucket").projectDir = new File(settingsDir, "../AndroidBucket"); -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/base/AIBean.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-12-2 12 | * Time: 上午10:29 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.FIELD) 16 | public @interface AIBean { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/base/AIChecked.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-11-30 12 | * Time: 下午8:03 13 | * To change this template use File | Settings | File Templates. 14 | */ 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target(ElementType.METHOD) 17 | public @interface AIChecked { 18 | int[] value() default {}; 19 | } 20 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/base/AIClick.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-11-30 12 | * Time: 下午8:03 13 | * To change this template use File | Settings | File Templates. 14 | */ 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target(ElementType.METHOD) 17 | public @interface AIClick { 18 | int[] value() default {}; 19 | } 20 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/base/AIFullScreen.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-12-4 12 | * Time: 下午3:03 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.TYPE) 16 | public @interface AIFullScreen { 17 | } 18 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/base/AIItemClick.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-11-30 12 | * Time: 下午8:03 13 | * To change this template use File | Settings | File Templates. 14 | */ 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target(ElementType.METHOD) 17 | public @interface AIItemClick { 18 | int[] value() default {}; 19 | } 20 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/base/AIItemLongClick.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-12-1 12 | * Time: 下午5:15 13 | * To change this template use File | Settings | File Templates. 14 | */ 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target(ElementType.METHOD) 17 | public @interface AIItemLongClick { 18 | int[] value() default {}; 19 | } 20 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/base/AILayout.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-11-29 12 | * Time: 下午2:38 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.TYPE) 16 | public @interface AILayout { 17 | int value(); 18 | } 19 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/base/AILongClick.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-11-30 12 | * Time: 下午8:03 13 | * To change this template use File | Settings | File Templates. 14 | */ 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target(ElementType.METHOD) 17 | public @interface AILongClick { 18 | int[] value() default {}; 19 | } 20 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/base/AINoTitle.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-12-4 12 | * Time: 下午3:03 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.TYPE) 16 | public @interface AINoTitle { 17 | } 18 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/base/AISystemService.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-12-2 12 | * Time: 下午5:00 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.FIELD) 16 | public @interface AISystemService { 17 | } 18 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/base/AIView.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.base; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-11-29 12 | * Time: 下午2:04 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.FIELD) 16 | public @interface AIView { 17 | int value() default -1; // 控件resId 18 | int id() default -1; // 控件resId 19 | String clickMethod() default ""; // 点击回调方法(方法参数必须只有一个View!) 20 | String longClickMethod() default ""; // 长按回调方法(方法参数必须只有一个View!) 21 | String itemClickMethod() default ""; // AdapterView的item点击回调 22 | String itemLongClickMethod() default ""; // AdapterView的item长按 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/dimens/AIScreenSize.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.dimens; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-12-2 12 | * Time: 上午10:29 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.FIELD) 16 | public @interface AIScreenSize { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/mvp/AIPresenter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.mvp; 2 | 3 | import com.wangjie.androidbucket.mvp.ABBasePresenter; 4 | import com.wangjie.androidbucket.mvp.ABInteractor; 5 | import com.wangjie.androidbucket.mvp.ABNoneInteractorImpl; 6 | import com.wangjie.androidbucket.mvp.ABNonePresenterImpl; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | /** 14 | * Created with IntelliJ IDEA. 15 | * Author: wangjie email: tiantian.china.2@gmail.com 16 | * Date: 13-12-2 17 | * Time: 上午10:29 18 | */ 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Target(ElementType.FIELD) 21 | public @interface AIPresenter { 22 | Class presenter() default ABNonePresenterImpl.class; 23 | 24 | Class interactor() default ABNoneInteractorImpl.class; 25 | } 26 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/net/AIDelete.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.net; 2 | 3 | import com.wangjie.androidbucket.services.network.http.HttpAccessParameter; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * @author Hubert He 12 | * @version V1.0 13 | * @Description 14 | * @Createdate 14-10-14 11:22 15 | */ 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Target(ElementType.METHOD) 18 | public @interface AIDelete { 19 | String value() default ""; 20 | 21 | /** 22 | * connectionTimeout, 连接一个url的连接等待时间 23 | * 24 | * @return 默认返回-1,时间由全局变量实现, Bucket包中HttpConfig配置 25 | */ 26 | int connTimeout() default -1; 27 | 28 | /** 29 | * SocketTimeout, 连接上一个url,获取response的返回等待时间 30 | * 31 | * @return 默认返回-1,时间由全局变量实现, Bucket包中HttpConfig配置 32 | */ 33 | int soTimeout() default -1; 34 | 35 | /** 36 | * 是否session连接 37 | * 38 | * @return 默认返回true 39 | */ 40 | HttpAccessParameter.SessionEnableMethod sessionEnable() default HttpAccessParameter.SessionEnableMethod.AUTO; 41 | } 42 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/net/AIGet.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.net; 2 | 3 | 4 | import com.wangjie.androidbucket.services.network.http.HttpAccessParameter; 5 | 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.RetentionPolicy; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * User: wangjie email: tiantian.china.2@gmail.com 14 | * Date: 13-11-30 15 | * Time: 下午8:03 16 | * To change this template use File | Settings | File Templates. 17 | */ 18 | @Retention(RetentionPolicy.RUNTIME) 19 | @Target(ElementType.METHOD) 20 | public @interface AIGet { 21 | String value() default ""; 22 | 23 | /** 24 | * connectionTimeout, 连接一个url的连接等待时间 25 | * 26 | * @return 默认返回-1,时间由全局变量实现, Bucket包中HttpConfig配置 27 | */ 28 | int connTimeout() default -1; 29 | 30 | /** 31 | * SocketTimeout, 连接上一个url,获取response的返回等待时间 32 | * 33 | * @return 默认返回-1,时间由全局变量实现, Bucket包中HttpConfig配置 34 | */ 35 | int soTimeout() default -1; 36 | 37 | /** 38 | * 是否session连接 39 | * 40 | * @return 默认返回true 41 | */ 42 | HttpAccessParameter.SessionEnableMethod sessionEnable() default HttpAccessParameter.SessionEnableMethod.AUTO; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/net/AIMapper.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.net; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-11-30 12 | * Time: 下午8:03 13 | * To change this template use File | Settings | File Templates. 14 | */ 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target(ElementType.TYPE) 17 | public @interface AIMapper { 18 | /** 19 | * Domain 20 | * 21 | * @return 22 | */ 23 | String value() default ""; 24 | } 25 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/net/AINetWorker.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.net; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-11-30 12 | * Time: 下午8:03 13 | * To change this template use File | Settings | File Templates. 14 | */ 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target(ElementType.FIELD) 17 | public @interface AINetWorker { 18 | String value() default ""; 19 | } 20 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/net/AIParam.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.net; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: wangjie email: tiantian.china.2@gmail.com 11 | * Date: 13-11-30 12 | * Time: 下午8:03 13 | * To change this template use File | Settings | File Templates. 14 | */ 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target(ElementType.PARAMETER) 17 | public @interface AIParam { 18 | String value() default ""; 19 | } 20 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/net/AIPost.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.net; 2 | 3 | 4 | import com.wangjie.androidbucket.services.network.http.HttpAccessParameter; 5 | 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.RetentionPolicy; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * User: wangjie email: tiantian.china.2@gmail.com 14 | * Date: 13-11-30 15 | * Time: 下午8:03 16 | * To change this template use File | Settings | File Templates. 17 | */ 18 | @Retention(RetentionPolicy.RUNTIME) 19 | @Target(ElementType.METHOD) 20 | public @interface AIPost { 21 | String value() default ""; 22 | 23 | /** 24 | * connectionTimeout, 连接一个url的连接等待时间 25 | * 26 | * @return 默认返回-1,时间由全局变量实现, Bucket包中HttpConfig配置 27 | */ 28 | int connTimeout() default -1; 29 | 30 | /** 31 | * SocketTimeout, 连接上一个url,获取response的返回等待时间 32 | * 33 | * @return 默认返回-1,时间由全局变量实现, Bucket包中HttpConfig配置 34 | */ 35 | int soTimeout() default -1; 36 | 37 | /** 38 | * 是否session连接 39 | * 40 | * @return 默认返回true 41 | */ 42 | HttpAccessParameter.SessionEnableMethod sessionEnable() default HttpAccessParameter.SessionEnableMethod.AUTO; 43 | } 44 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/net/AIRaw.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.net; 2 | 3 | import com.wangjie.androidbucket.services.network.http.HttpAccessParameter; 4 | import com.wangjie.androidbucket.services.network.http.HttpConstants; 5 | 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.RetentionPolicy; 9 | import java.lang.annotation.Target; 10 | 11 | /** 12 | * @author Hubert He 13 | * @version V1.0 14 | * @Description 15 | * @Createdate 14-9-5 10:34 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target(ElementType.METHOD) 19 | public @interface AIRaw { 20 | 21 | String value() default ""; 22 | 23 | /** 24 | * connectionTimeout, 连接一个url的连接等待时间 25 | * 26 | * @return 默认返回-1,时间由全局变量实现, Bucket包中HttpConfig配置 27 | */ 28 | int connTimeout() default -1; 29 | 30 | /** 31 | * SocketTimeout, 连接上一个url,获取response的返回等待时间 32 | * 33 | * @return 默认返回-1,时间由全局变量实现, Bucket包中HttpConfig配置 34 | */ 35 | int soTimeout() default -1; 36 | 37 | String contentType() default HttpConstants.CONTENT_TYPE_JSON; 38 | 39 | /** 40 | * 是否session连接 41 | * 42 | * @return 默认返回true 43 | */ 44 | HttpAccessParameter.SessionEnableMethod sessionEnable() default HttpAccessParameter.SessionEnableMethod.AUTO; 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/orm/AIColumn.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.orm; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email:tiantian.china.2@gmail.com 11 | * Date: 14-3-24 12 | * Time: 下午4:39 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.FIELD) 16 | public @interface AIColumn 17 | { 18 | /** 19 | * 表示要映射到的表字段名称,不填写则默认以属性名作为表字段名 20 | * @return 21 | */ 22 | String value() default ""; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/orm/AIPrimaryKey.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.orm; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email:tiantian.china.2@gmail.com 11 | * Date: 14-3-24 12 | * Time: 下午4:39 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.FIELD) 16 | public @interface AIPrimaryKey 17 | { 18 | /** 19 | * 表示插入数据时是否同时也插入主键到表。默认为false,即表的主键应该为自动生成 20 | * @return 21 | */ 22 | boolean insertable() default false; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/annotations/orm/AITable.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.annotations.orm; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email:tiantian.china.2@gmail.com 11 | * Date: 14-3-24 12 | * Time: 下午4:39 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(ElementType.TYPE) 16 | public @interface AITable 17 | { 18 | /** 19 | * 表示要映射到的表的名称,不填写或未增加该注解则默认以类名小写为表名 20 | * @return 21 | */ 22 | String value() default ""; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/FieldCache.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache; 2 | 3 | import com.wangjie.androidinject.annotation.present.AIPresent; 4 | 5 | import java.lang.annotation.Annotation; 6 | import java.lang.reflect.Field; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | /** 12 | * Author: wangjie 13 | * Email: tiantian.china.2@gmail.com 14 | * Date: 3/23/15. 15 | */ 16 | @Deprecated 17 | public class FieldCache { 18 | private static final String TAG = FieldCache.class.getSimpleName(); 19 | @Deprecated 20 | public static class CachedField{ 21 | private Field field; 22 | private Annotation[] annotations; 23 | 24 | public Annotation[] getAnnotations() { 25 | return annotations; 26 | } 27 | 28 | public void setAnnotations(Annotation[] annotations) { 29 | this.annotations = annotations; 30 | } 31 | 32 | public Field getField() { 33 | return field; 34 | } 35 | 36 | public void setField(Field field) { 37 | this.field = field; 38 | } 39 | } 40 | 41 | private static FieldCache instance; 42 | 43 | public synchronized static FieldCache getInstance() { 44 | if (null == instance) { 45 | instance = new FieldCache(); 46 | } 47 | return instance; 48 | } 49 | 50 | private FieldCache() { 51 | } 52 | 53 | private ConcurrentHashMap, List> cacheMapper = new ConcurrentHashMap<>(); 54 | 55 | public List getCache(Class key) { 56 | List cachedFields = cacheMapper.get(key); 57 | if (null == cachedFields) { 58 | cachedFields = new ArrayList<>(); 59 | 60 | Field[] fields = key.getDeclaredFields(); 61 | for (Field field : fields) { 62 | CachedField cachedField = new CachedField(); 63 | cachedField.setField(field); 64 | cachedField.setAnnotations(field.getAnnotations()); 65 | cachedFields.add(cachedField); 66 | } 67 | cacheMapper.put(key, cachedFields); 68 | // Logger.i(TAG, key.getName() + " fields find with reflect..., fields: " + cachedFields); 69 | } 70 | return cachedFields; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/MethodCache.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache; 2 | 3 | import com.wangjie.androidinject.annotation.present.AIPresent; 4 | 5 | import java.lang.annotation.Annotation; 6 | import java.lang.reflect.Method; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | /** 12 | * Author: wangjie 13 | * Email: tiantian.china.2@gmail.com 14 | * Date: 3/23/15. 15 | */ 16 | @Deprecated 17 | public class MethodCache { 18 | private static final String TAG = MethodCache.class.getSimpleName(); 19 | @Deprecated 20 | public static class CachedMethod { 21 | private Method method; 22 | private Annotation[] annotations; 23 | 24 | public Annotation[] getAnnotations() { 25 | return annotations; 26 | } 27 | 28 | public void setAnnotations(Annotation[] annotations) { 29 | this.annotations = annotations; 30 | } 31 | 32 | public Method getMethod() { 33 | return method; 34 | } 35 | 36 | public void setMethod(Method method) { 37 | this.method = method; 38 | } 39 | } 40 | 41 | private static MethodCache instance; 42 | 43 | public synchronized static MethodCache getInstance() { 44 | if (null == instance) { 45 | instance = new MethodCache(); 46 | } 47 | return instance; 48 | } 49 | 50 | private MethodCache() { 51 | } 52 | 53 | private ConcurrentHashMap, List> cacheMapper = new ConcurrentHashMap<>(); 54 | 55 | public List getCache(Class key) { 56 | List cachedMethods = cacheMapper.get(key); 57 | if (null == cachedMethods) { 58 | cachedMethods = new ArrayList<>(); 59 | 60 | Method[] methods = key.getDeclaredMethods(); 61 | for (Method method : methods) { 62 | CachedMethod cachedMethod = new CachedMethod(); 63 | cachedMethod.setMethod(method); 64 | cachedMethod.setAnnotations(method.getAnnotations()); 65 | cachedMethods.add(cachedMethod); 66 | } 67 | cacheMapper.put(key, cachedMethods); 68 | // Logger.i(TAG, key.getName() + " melthods find with reflect..., methods: " + cachedMethods); 69 | } 70 | return cachedMethods; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/ProcessorCache.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache; 2 | 3 | import com.wangjie.androidbucket.log.Logger; 4 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 5 | import com.wangjie.androidinject.annotation.present.common.AnnoProcessorAlias; 6 | 7 | import java.lang.annotation.Annotation; 8 | import java.util.concurrent.ConcurrentHashMap; 9 | 10 | /** 11 | * Author: wangjie 12 | * Email: tiantian.china.2@gmail.com 13 | * Date: 3/23/15. 14 | */ 15 | @Deprecated 16 | public class ProcessorCache { 17 | private static final String TAG = ProcessorCache.class.getSimpleName(); 18 | 19 | private ProcessorCache() { 20 | } 21 | 22 | private static ProcessorCache instance; 23 | 24 | public synchronized static ProcessorCache getInstance() { 25 | if (null == instance) { 26 | instance = new ProcessorCache(); 27 | } 28 | return instance; 29 | } 30 | 31 | /** 32 | * 缓存所有注解的处理器实例 33 | */ 34 | private ConcurrentHashMap, AIAnnotationProcessor> processorMapper = new ConcurrentHashMap<>(); 35 | 36 | public AIAnnotationProcessor getAnnotationProcessor(Class annotationClazz) { 37 | // 如果缓存中有该处理器,则直接复用 38 | AIAnnotationProcessor annotationProcessor = processorMapper.get(annotationClazz); 39 | if (null != annotationProcessor) { 40 | return annotationProcessor; 41 | } 42 | 43 | // 如果没有,则先找出该处理器类型,然后实例化并放入缓存中 44 | AnnoProcessorAlias annotationProcessorAlias = AnnoProcessorAlias.getAnnotationProcessorAlias(annotationClazz); 45 | Class annotationProcessorClazz; 46 | if (null == annotationProcessorAlias || null == (annotationProcessorClazz = annotationProcessorAlias.getProcessorClazz())) { 47 | return null; 48 | } 49 | try { 50 | annotationProcessor = annotationProcessorClazz.newInstance(); 51 | processorMapper.put(annotationClazz, annotationProcessor); 52 | // Logger.i(TAG, "processor new instance: " + annotationProcessorClazz.getSimpleName()); 53 | } catch (InstantiationException | IllegalAccessException e) { 54 | Logger.e(TAG, e); 55 | } 56 | return annotationProcessor; 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/TypeCache.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache; 2 | 3 | import com.wangjie.androidinject.annotation.present.AIPresent; 4 | 5 | import java.lang.annotation.Annotation; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | 8 | /** 9 | * Author: wangjie 10 | * Email: tiantian.china.2@gmail.com 11 | * Date: 3/23/15. 12 | */ 13 | @Deprecated 14 | public class TypeCache { 15 | private static final String TAG = TypeCache.class.getSimpleName(); 16 | @Deprecated 17 | public static class CachedType { 18 | private Annotation[] annotations; 19 | 20 | public Annotation[] getAnnotations() { 21 | return annotations; 22 | } 23 | 24 | public void setAnnotations(Annotation[] annotations) { 25 | this.annotations = annotations; 26 | } 27 | } 28 | 29 | private static TypeCache instance; 30 | 31 | public synchronized static TypeCache getInstance() { 32 | if (null == instance) { 33 | instance = new TypeCache(); 34 | } 35 | return instance; 36 | } 37 | 38 | private TypeCache() { 39 | } 40 | 41 | private ConcurrentHashMap, CachedType> typeMapper = new ConcurrentHashMap<>(); 42 | 43 | public CachedType getCache(Class key) { 44 | CachedType cachedType = typeMapper.get(key); 45 | if (null == cachedType) { 46 | cachedType = new CachedType(); 47 | cachedType.setAnnotations(key.getAnnotations()); 48 | typeMapper.put(key, cachedType); 49 | // Logger.i(TAG, key.getName() + " type find with reflect..., type: " + cachedType); 50 | } 51 | return cachedType; 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/common/Cacheable.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache.common; 2 | 3 | /** 4 | * Author: wangjie 5 | * Email: tiantian.china.2@gmail.com 6 | * Date: 3/25/15. 7 | */ 8 | public interface Cacheable { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/common/CommonCache.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache.common; 2 | 3 | import com.wangjie.androidbucket.log.Logger; 4 | import com.wangjie.androidinject.annotation.cache.common.generator.CachedGenerator; 5 | import com.wangjie.androidinject.annotation.exception.AINoSuchAnnotationProcessorException; 6 | 7 | import java.util.HashMap; 8 | 9 | /** 10 | * Author: wangjie 11 | * Email: tiantian.china.2@gmail.com 12 | * Date: 3/25/15. 13 | */ 14 | public class CommonCache { 15 | private static final String TAG = CommonCache.class.getSimpleName(); 16 | 17 | private static CommonCache instance; 18 | 19 | public synchronized static CommonCache getInstance() { 20 | if (null == instance) { 21 | instance = new CommonCache(); 22 | } 23 | return instance; 24 | } 25 | 26 | private CommonCache() { 27 | } 28 | 29 | /** 30 | * 缓存map,tag表示缓存的分组 31 | * 每一个分组中都有一个HashMap,这个HashMap中根据key进行储存 32 | */ 33 | private HashMap< 34 | String, 35 | HashMap 36 | > 37 | cacheMapper = new HashMap<>(); 38 | 39 | public T getCache(Class cacheableClazz, Object key, CachedGenerator cachedGenerator) throws Exception { 40 | return getCache(cacheableClazz, cacheableClazz.getName(), key, cachedGenerator); 41 | } 42 | 43 | public T getCache(Class cacheableClazz, String tag, Object key, CachedGenerator cachedGenerator) throws Exception{ 44 | HashMap cachedableMapper = cacheMapper.get(tag); 45 | if (null == cachedableMapper) { 46 | cachedableMapper = new HashMap<>(); 47 | cacheMapper.put(tag, cachedableMapper); 48 | } 49 | T cacheable = (T) cachedableMapper.get(key); 50 | if (null == cacheable) { 51 | try { 52 | cacheable = cachedGenerator.generate(); 53 | cachedableMapper.put(key, cacheable); 54 | Logger.i(TAG, "CommonCache generate instance to cache, tag: " + tag + ", key: " + key + ", cacheable: " + cacheable); 55 | } catch (AINoSuchAnnotationProcessorException e) { 56 | Logger.i(TAG, "[WARN Cacheable generate null]CommonCache generate instance to cache, tag: " + tag + ", key: " + key); 57 | }/* catch (AIInjectFailedException e){ 58 | throw e; 59 | }*/ 60 | } 61 | return cacheable; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/common/cached/CachedField.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache.common.cached; 2 | 3 | import com.wangjie.androidinject.annotation.cache.common.Cacheable; 4 | 5 | import java.lang.annotation.Annotation; 6 | import java.lang.reflect.Field; 7 | 8 | /** 9 | * Author: wangjie 10 | * Email: tiantian.china.2@gmail.com 11 | * Date: 3/25/15. 12 | */ 13 | public class CachedField implements Cacheable { 14 | private Field field; 15 | private Annotation[] annotations; 16 | 17 | public Annotation[] getAnnotations() { 18 | return annotations; 19 | } 20 | 21 | public void setAnnotations(Annotation[] annotations) { 22 | this.annotations = annotations; 23 | } 24 | 25 | public Field getField() { 26 | return field; 27 | } 28 | 29 | public void setField(Field field) { 30 | this.field = field; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/common/cached/CachedMethod.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache.common.cached; 2 | 3 | import com.wangjie.androidinject.annotation.cache.common.Cacheable; 4 | 5 | import java.lang.annotation.Annotation; 6 | import java.lang.reflect.Method; 7 | 8 | /** 9 | * Author: wangjie 10 | * Email: tiantian.china.2@gmail.com 11 | * Date: 3/26/15. 12 | */ 13 | public class CachedMethod implements Cacheable { 14 | private Method method; 15 | private Annotation[] annotations; 16 | 17 | public Method getMethod() { 18 | return method; 19 | } 20 | 21 | public void setMethod(Method method) { 22 | this.method = method; 23 | } 24 | 25 | public Annotation[] getAnnotations() { 26 | return annotations; 27 | } 28 | 29 | public void setAnnotations(Annotation[] annotations) { 30 | this.annotations = annotations; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/common/cached/CachedPresentFields.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache.common.cached; 2 | 3 | import com.wangjie.androidinject.annotation.cache.common.Cacheable; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Author: wangjie 9 | * Email: tiantian.china.2@gmail.com 10 | * Date: 3/25/15. 11 | */ 12 | public class CachedPresentFields implements Cacheable{ 13 | private List cachedFields; 14 | 15 | public List getCachedFields() { 16 | return cachedFields; 17 | } 18 | 19 | public void setCachedFields(List cachedFields) { 20 | this.cachedFields = cachedFields; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/common/cached/CachedPresentMethods.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache.common.cached; 2 | 3 | import com.wangjie.androidinject.annotation.cache.common.Cacheable; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Author: wangjie 9 | * Email: tiantian.china.2@gmail.com 10 | * Date: 3/26/15. 11 | */ 12 | public class CachedPresentMethods implements Cacheable { 13 | private List cachedMethods; 14 | 15 | public List getCachedMethods() { 16 | return cachedMethods; 17 | } 18 | 19 | public void setCachedMethods(List cachedMethods) { 20 | this.cachedMethods = cachedMethods; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/common/cached/CachedPresentType.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache.common.cached; 2 | 3 | import com.wangjie.androidinject.annotation.cache.common.Cacheable; 4 | 5 | import java.lang.annotation.Annotation; 6 | 7 | /** 8 | * Author: wangjie 9 | * Email: tiantian.china.2@gmail.com 10 | * Date: 3/26/15. 11 | */ 12 | public class CachedPresentType implements Cacheable { 13 | private Annotation[] annotations; 14 | 15 | public Annotation[] getAnnotations() { 16 | return annotations; 17 | } 18 | 19 | public void setAnnotations(Annotation[] annotations) { 20 | this.annotations = annotations; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/common/generator/CachedAnnotationProcessorGenerator.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache.common.generator; 2 | 3 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 4 | import com.wangjie.androidinject.annotation.exception.AINoSuchAnnotationProcessorException; 5 | import com.wangjie.androidinject.annotation.present.common.AnnoProcessorAlias; 6 | 7 | import java.lang.annotation.Annotation; 8 | 9 | /** 10 | * 注解处理器的缓存生成器 11 | * Author: wangjie 12 | * Email: tiantian.china.2@gmail.com 13 | * Date: 3/26/15. 14 | */ 15 | public class CachedAnnotationProcessorGenerator implements CachedGenerator { 16 | private static final String TAG = CachedAnnotationProcessorGenerator.class.getSimpleName(); 17 | private Class annotationClazz; 18 | 19 | public void setAnnotationClazz(Class annotationClazz) { 20 | this.annotationClazz = annotationClazz; 21 | } 22 | 23 | @Override 24 | public AIAnnotationProcessor generate() throws Exception { 25 | // 如果没有,则先找出该处理器类型,然后实例化并放入缓存中 26 | AnnoProcessorAlias annotationProcessorAlias = AnnoProcessorAlias.getAnnotationProcessorAlias(annotationClazz); 27 | Class annotationProcessorClazz; 28 | if (null == annotationProcessorAlias || null == (annotationProcessorClazz = annotationProcessorAlias.getProcessorClazz())) { 29 | throw new AINoSuchAnnotationProcessorException("Can not found the processor which parser the annotation [" + annotationClazz + "]"); 30 | } 31 | try { 32 | AIAnnotationProcessor aiAnnotationProcessor = annotationProcessorClazz.newInstance(); 33 | return aiAnnotationProcessor; 34 | } catch (Exception e) { 35 | throw new Exception(annotationProcessorClazz + " instance failed!"); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/common/generator/CachedGenerator.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache.common.generator; 2 | 3 | /** 4 | * Author: wangjie 5 | * Email: tiantian.china.2@gmail.com 6 | * Date: 3/25/15. 7 | */ 8 | public interface CachedGenerator { 9 | T generate() throws Exception; 10 | } 11 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/common/generator/CachedPresentFieldsGenerator.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache.common.generator; 2 | 3 | import com.wangjie.androidinject.annotation.cache.common.cached.CachedField; 4 | import com.wangjie.androidinject.annotation.cache.common.cached.CachedPresentFields; 5 | import com.wangjie.androidinject.annotation.present.AIPresent; 6 | 7 | import java.lang.reflect.Field; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Author: wangjie 13 | * Email: tiantian.china.2@gmail.com 14 | * Date: 3/26/15. 15 | */ 16 | public class CachedPresentFieldsGenerator implements CachedGenerator{ 17 | private Class clazz; 18 | 19 | public void setClazz(Class clazz) { 20 | this.clazz = clazz; 21 | } 22 | 23 | @Override 24 | public CachedPresentFields generate() throws Exception { 25 | CachedPresentFields cs = new CachedPresentFields(); 26 | List cachedFields = new ArrayList<>(); 27 | Field[] fields = clazz.getDeclaredFields(); 28 | for (Field field : fields) { 29 | CachedField cachedField = new CachedField(); 30 | cachedField.setField(field); 31 | cachedField.setAnnotations(field.getAnnotations()); 32 | cachedFields.add(cachedField); 33 | } 34 | cs.setCachedFields(cachedFields); 35 | return cs; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/common/generator/CachedPresentMethodsGenerator.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache.common.generator; 2 | 3 | import com.wangjie.androidinject.annotation.cache.common.cached.CachedMethod; 4 | import com.wangjie.androidinject.annotation.cache.common.cached.CachedPresentMethods; 5 | import com.wangjie.androidinject.annotation.present.AIPresent; 6 | 7 | import java.lang.reflect.Method; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Author: wangjie 13 | * Email: tiantian.china.2@gmail.com 14 | * Date: 3/26/15. 15 | */ 16 | public class CachedPresentMethodsGenerator implements CachedGenerator { 17 | private Class clazz; 18 | 19 | public void setClazz(Class clazz) { 20 | this.clazz = clazz; 21 | } 22 | 23 | @Override 24 | public CachedPresentMethods generate() throws Exception { 25 | CachedPresentMethods cs = new CachedPresentMethods(); 26 | List cachedMethods = new ArrayList<>(); 27 | Method[] methods = clazz.getDeclaredMethods(); 28 | for (Method method : methods) { 29 | CachedMethod cachedField = new CachedMethod(); 30 | cachedField.setMethod(method); 31 | cachedField.setAnnotations(method.getAnnotations()); 32 | cachedMethods.add(cachedField); 33 | } 34 | cs.setCachedMethods(cachedMethods); 35 | return cs; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/cache/common/generator/CachedPresentTypeGenerator.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.cache.common.generator; 2 | 3 | import com.wangjie.androidinject.annotation.cache.common.cached.CachedPresentType; 4 | import com.wangjie.androidinject.annotation.present.AIPresent; 5 | 6 | /** 7 | * Author: wangjie 8 | * Email: tiantian.china.2@gmail.com 9 | * Date: 3/26/15. 10 | */ 11 | public class CachedPresentTypeGenerator implements CachedGenerator { 12 | private Class clazz; 13 | 14 | public void setClazz(Class clazz) { 15 | this.clazz = clazz; 16 | } 17 | 18 | @Override 19 | public CachedPresentType generate() throws Exception { 20 | CachedPresentType cachedPresentType = new CachedPresentType(); 21 | cachedPresentType.setAnnotations(clazz.getAnnotations()); 22 | return cachedPresentType; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/AnnotationManager.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base; 2 | 3 | import android.content.Context; 4 | import com.wangjie.androidbucket.log.Logger; 5 | import com.wangjie.androidinject.annotation.present.AIPresent; 6 | 7 | /** 8 | * 注解core,用于实现AIPresent中的注解 9 | *

10 | * Created with IntelliJ IDEA. 11 | * Author: wangjie email: tiantian.china.2@gmail.com 12 | * Date: 13-11-29 13 | * Time: 下午3:52 14 | */ 15 | public class AnnotationManager { 16 | public static final String TAG = AnnotationManager.class.getSimpleName(); 17 | 18 | private Context context; 19 | private AIPresent present; 20 | private Class clazz; 21 | 22 | public AnnotationManager(AIPresent present) { 23 | this.context = present.getContext(); 24 | this.present = present; 25 | this.clazz = present.getClass(); 26 | } 27 | 28 | /** 29 | * 反射实现注解功能 30 | */ 31 | public void initAnnotations() throws Exception { 32 | Logger.i(TAG, "[============================================="); 33 | long start = System.nanoTime(); 34 | RealizeTypeAnnotation.getInstance(present).processAnnotation(); 35 | Logger.i(TAG, clazz.getSimpleName() + ", realize type takes: " + (System.nanoTime() - start)); 36 | 37 | start = System.nanoTime(); 38 | RealizeFieldAnnotation.getInstance(present).processAnnotation(); 39 | Logger.i(TAG, clazz.getSimpleName() + ", realize field takes: " + (System.nanoTime() - start)); 40 | 41 | start = System.nanoTime(); 42 | RealizeMethodAnnotation.getInstance(present).processAnnotation(); 43 | Logger.i(TAG, clazz.getSimpleName() + ", realize method takes: " + (System.nanoTime() - start)); 44 | Logger.i(TAG, "=============================================]"); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/ParticularAnnotation.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base; 2 | 3 | import android.view.LayoutInflater; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | import com.wangjie.androidinject.annotation.annotations.base.AILayout; 7 | import com.wangjie.androidinject.annotation.present.AIPresent; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * Author: wangjie email: tiantian.china.2@gmail.com 12 | * Date: 13-12-4 13 | * Time: 下午5:12 14 | */ 15 | public class ParticularAnnotation { 16 | 17 | public static View realizeLayoutAnnotation(AIPresent present, LayoutInflater inflater, ViewGroup container){ 18 | if(!present.getClass().isAnnotationPresent(AILayout.class)){ 19 | return null; 20 | } 21 | 22 | AILayout aiLayout = present.getClass().getAnnotation(AILayout.class); 23 | return inflater.inflate(aiLayout.value(), container, false); 24 | 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/RealizeAnnotation.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * User: wangjie email: tiantian.china.2@gmail.com 6 | * Date: 13-12-1 7 | * Time: 下午4:22 8 | * To change this template use File | Settings | File Templates. 9 | */ 10 | public interface RealizeAnnotation { 11 | public void processAnnotation() throws Exception; 12 | } 13 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/RealizeFieldAnnotation.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base; 2 | 3 | import com.wangjie.androidinject.annotation.cache.common.CommonCache; 4 | import com.wangjie.androidinject.annotation.cache.common.cached.CachedField; 5 | import com.wangjie.androidinject.annotation.cache.common.cached.CachedPresentFields; 6 | import com.wangjie.androidinject.annotation.cache.common.generator.CachedPresentFieldsGenerator; 7 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 8 | import com.wangjie.androidinject.annotation.present.AIPresent; 9 | import com.wangjie.androidinject.annotation.present.common.AnnoProcessorAlias; 10 | 11 | import java.lang.annotation.Annotation; 12 | import java.lang.reflect.Field; 13 | 14 | /** 15 | * Created with IntelliJ IDEA. 16 | * User: wangjie email: tiantian.china.2@gmail.com 17 | * Date: 13-11-30 18 | * Time: 下午7:23 19 | * To change this template use File | Settings | File Templates. 20 | */ 21 | public class RealizeFieldAnnotation implements RealizeAnnotation { 22 | private static final String TAG = RealizeFieldAnnotation.class.getSimpleName(); 23 | // private static Map, RealizeFieldAnnotation> map = new HashMap, RealizeFieldAnnotation>(); 24 | 25 | public static RealizeFieldAnnotation getInstance(AIPresent present) { 26 | // Class clazz = present.getClass(); 27 | // RealizeFieldAnnotation realize = map.get(clazz); 28 | // if (null == realize) { 29 | // realize = new RealizeFieldAnnotation(); 30 | // map.put(clazz, realize); 31 | // } 32 | RealizeFieldAnnotation realize = new RealizeFieldAnnotation(); 33 | realize.setPresent(present); 34 | realize.setClazz(present.getClass()); 35 | return realize; 36 | } 37 | 38 | 39 | private AIPresent present; 40 | private Class clazz; 41 | 42 | private CachedPresentFieldsGenerator cachedPresentFieldsGenerator = new CachedPresentFieldsGenerator(); 43 | 44 | /** 45 | * 实现present控件注解功能 46 | * 47 | * @throws Exception 48 | */ 49 | @Override 50 | public void processAnnotation() throws Exception { 51 | // List cachedFields = FieldCache.getInstance().getCache(clazz); 52 | // for (FieldCache.CachedField cachedField : cachedFields) { 53 | // Annotation[] annotations = cachedField.getAnnotations(); 54 | // Field field = cachedField.getField(); 55 | // for (Annotation annotation : annotations) { 56 | // AIAnnotationProcessor processor = ProcessorCache.getInstance().getAnnotationProcessor(annotation.annotationType()); 57 | // if (null == processor) { 58 | // continue; 59 | // } 60 | // try { 61 | // processor.process(present, field); 62 | // } catch (Exception ex) { 63 | // Logger.e(TAG, ex); 64 | // } 65 | // } 66 | // present.parserFieldAnnotations(field); 67 | // } 68 | 69 | 70 | cachedPresentFieldsGenerator.setClazz(clazz); 71 | CachedPresentFields cachedPresentFields = CommonCache.getInstance().getCache(CachedPresentFields.class, clazz, cachedPresentFieldsGenerator); 72 | 73 | for (CachedField cachedField : cachedPresentFields.getCachedFields()) { 74 | Annotation[] annotations = cachedField.getAnnotations(); 75 | Field field = cachedField.getField(); 76 | for (Annotation annotation : annotations) { 77 | AIAnnotationProcessor processor = AnnoProcessorAlias.getCachedAnnotationProcessor(annotation.annotationType()); 78 | if (null == processor) { 79 | continue; 80 | } 81 | // try { 82 | processor.process(present, field); 83 | // } catch (Exception ex) { 84 | // Logger.e(TAG, ex); 85 | // } 86 | } 87 | present.parserFieldAnnotations(field); 88 | } 89 | 90 | 91 | } 92 | 93 | public void setClazz(Class clazz) { 94 | this.clazz = clazz; 95 | } 96 | 97 | public void setPresent(AIPresent present) { 98 | this.present = present; 99 | } 100 | 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/RealizeMethodAnnotation.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base; 2 | 3 | import com.wangjie.androidbucket.log.Logger; 4 | import com.wangjie.androidinject.annotation.cache.common.CommonCache; 5 | import com.wangjie.androidinject.annotation.cache.common.cached.CachedMethod; 6 | import com.wangjie.androidinject.annotation.cache.common.cached.CachedPresentMethods; 7 | import com.wangjie.androidinject.annotation.cache.common.generator.CachedPresentMethodsGenerator; 8 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 9 | import com.wangjie.androidinject.annotation.present.AIPresent; 10 | import com.wangjie.androidinject.annotation.present.common.AnnoProcessorAlias; 11 | 12 | import java.lang.annotation.Annotation; 13 | import java.lang.reflect.Method; 14 | 15 | /** 16 | * Created with IntelliJ IDEA. 17 | * User: wangjie email: tiantian.china.2@gmail.com 18 | * Date: 13-11-30 19 | * Time: 下午7:23 20 | * To change this template use File | Settings | File Templates. 21 | */ 22 | public class RealizeMethodAnnotation implements RealizeAnnotation { 23 | private static final String TAG = RealizeMethodAnnotation.class.getSimpleName(); 24 | // private static Map, RealizeMethodAnnotation> map = new HashMap, RealizeMethodAnnotation>(); 25 | 26 | public static RealizeMethodAnnotation getInstance(AIPresent present) { 27 | // Class clazz = present.getClass(); 28 | // RealizeMethodAnnotation realize = map.get(clazz); 29 | // if (null == realize) { 30 | // realize = new RealizeMethodAnnotation(); 31 | // map.put(clazz, realize); 32 | // } 33 | RealizeMethodAnnotation realize = new RealizeMethodAnnotation(); 34 | realize.setPresent(present); 35 | realize.setClazz(present.getClass()); 36 | return realize; 37 | } 38 | 39 | 40 | private AIPresent present; 41 | private Class clazz; 42 | private CachedPresentMethodsGenerator cachedPresentFieldsGenerator = new CachedPresentMethodsGenerator(); 43 | 44 | @Override 45 | public void processAnnotation() throws Exception { 46 | // List cachedMethods = MethodCache.getInstance().getCache(clazz); 47 | // for (MethodCache.CachedMethod cachedMethod : cachedMethods) { 48 | // Annotation[] annotations = cachedMethod.getAnnotations(); 49 | // Method method = cachedMethod.getMethod(); 50 | // for (Annotation annotation : annotations) { 51 | // AIAnnotationProcessor processor = ProcessorCache.getInstance().getAnnotationProcessor(annotation.annotationType()); 52 | // if (null == processor) { 53 | // continue; 54 | // } 55 | // try { 56 | // processor.process(present, method); 57 | // } catch (Exception ex) { 58 | // Logger.e(TAG, ex); 59 | // } 60 | // } 61 | // 62 | // present.parserMethodAnnotations(method); 63 | // } 64 | 65 | cachedPresentFieldsGenerator.setClazz(clazz); 66 | CachedPresentMethods cachedPresentMethods = CommonCache.getInstance().getCache(CachedPresentMethods.class, clazz, cachedPresentFieldsGenerator); 67 | for (CachedMethod cachedMethod : cachedPresentMethods.getCachedMethods()) { 68 | Annotation[] annotations = cachedMethod.getAnnotations(); 69 | Method method = cachedMethod.getMethod(); 70 | for (Annotation annotation : annotations) { 71 | AIAnnotationProcessor processor = AnnoProcessorAlias.getCachedAnnotationProcessor(annotation.annotationType()); 72 | if (null == processor) { 73 | continue; 74 | } 75 | try { 76 | processor.process(present, method); 77 | } catch (Exception ex) { 78 | Logger.e(TAG, ex); 79 | } 80 | } 81 | present.parserMethodAnnotations(method); 82 | } 83 | 84 | 85 | } 86 | 87 | 88 | public void setClazz(Class clazz) { 89 | this.clazz = clazz; 90 | } 91 | 92 | public void setPresent(AIPresent present) { 93 | this.present = present; 94 | } 95 | 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/RealizeTypeAnnotation.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base; 2 | 3 | import com.wangjie.androidinject.annotation.cache.common.CommonCache; 4 | import com.wangjie.androidinject.annotation.cache.common.cached.CachedPresentType; 5 | import com.wangjie.androidinject.annotation.cache.common.generator.CachedPresentTypeGenerator; 6 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 7 | import com.wangjie.androidinject.annotation.present.AIPresent; 8 | import com.wangjie.androidinject.annotation.present.common.AnnoProcessorAlias; 9 | 10 | import java.lang.annotation.Annotation; 11 | 12 | /** 13 | * Created with IntelliJ IDEA. 14 | * User: wangjie email: tiantian.china.2@gmail.com 15 | * Date: 13-11-30 16 | * Time: 下午7:23 17 | * To change this template use File | Settings | File Templates. 18 | */ 19 | public class RealizeTypeAnnotation implements RealizeAnnotation { 20 | private static final String TAG = RealizeTypeAnnotation.class.getSimpleName(); 21 | // private static Map, RealizeTypeAnnotation> map = new HashMap<>(); 22 | 23 | public static RealizeTypeAnnotation getInstance(AIPresent present) { 24 | // Class clazz = present.getClass(); 25 | // RealizeTypeAnnotation realize = map.get(clazz); 26 | // if (null == realize) { 27 | // realize = new RealizeTypeAnnotation(); 28 | // map.put(clazz, realize); 29 | // } 30 | // realize.setPresent(present); 31 | // realize.setClazz(clazz); 32 | RealizeTypeAnnotation realize = new RealizeTypeAnnotation(); 33 | realize.setPresent(present); 34 | realize.setClazz(present.getClass()); 35 | return realize; 36 | } 37 | 38 | private AIPresent present; 39 | private Class clazz; 40 | 41 | private CachedPresentTypeGenerator cachedPresentTypeGenerator = new CachedPresentTypeGenerator(); 42 | 43 | /** 44 | * 实现present类注解功能 45 | * 46 | * @throws Exception 47 | */ 48 | @Override 49 | public void processAnnotation() throws Exception { 50 | cachedPresentTypeGenerator.setClazz(clazz); 51 | CachedPresentType cachedPresentType = CommonCache.getInstance().getCache(CachedPresentType.class, clazz, cachedPresentTypeGenerator); 52 | 53 | Annotation[] annotations = cachedPresentType.getAnnotations(); 54 | for (Annotation annotation : annotations) { 55 | AIAnnotationProcessor processor = AnnoProcessorAlias.getCachedAnnotationProcessor(annotation.annotationType()); 56 | if (null == processor) { 57 | continue; 58 | } 59 | // try { 60 | processor.process(present, clazz); 61 | // } catch (Exception ex) { 62 | // Logger.e(TAG, ex); 63 | // } 64 | } 65 | present.parserTypeAnnotations(clazz); 66 | 67 | } 68 | 69 | 70 | public void setClazz(Class clazz) { 71 | this.clazz = clazz; 72 | } 73 | 74 | public void setPresent(AIPresent present) { 75 | this.present = present; 76 | } 77 | 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/AIAnnotationProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process; 2 | 3 | import com.wangjie.androidinject.annotation.cache.common.Cacheable; 4 | import com.wangjie.androidinject.annotation.present.AIPresent; 5 | 6 | /** 7 | * Author: wangjie 8 | * Email: tiantian.china.2@gmail.com 9 | * Date: 2/4/15. 10 | */ 11 | public interface AIAnnotationProcessor extends Cacheable { 12 | void process(AIPresent present, T obj) throws Exception; 13 | } 14 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/field/AIBeanFieldProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.field; 2 | 3 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 4 | import com.wangjie.androidinject.annotation.present.AIPresent; 5 | 6 | import java.lang.reflect.Field; 7 | 8 | /** 9 | * Author: wangjie 10 | * Email: tiantian.china.2@gmail.com 11 | * Date: 2/4/15. 12 | */ 13 | public class AIBeanFieldProcessor implements AIAnnotationProcessor { 14 | 15 | @Override 16 | public void process(AIPresent present, Field field) throws Exception { 17 | try { 18 | field.getType().getConstructor(); 19 | } catch (NoSuchMethodException e) { 20 | throw new Exception(field.getType() + " must has a default constructor (a no-args constructor)! " + e.getMessage()); 21 | } 22 | field.setAccessible(true); 23 | try { 24 | field.set(present, field.getType().newInstance()); 25 | } catch (Exception e) { 26 | throw new Exception("Bean newInstance() failed! " + e.getMessage()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/field/AINetWorkerFieldProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.field; 2 | 3 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 4 | import com.wangjie.androidinject.annotation.core.net.NetInvoHandler; 5 | import com.wangjie.androidinject.annotation.present.AIPresent; 6 | 7 | import java.lang.reflect.Field; 8 | 9 | /** 10 | * Author: wangjie 11 | * Email: tiantian.china.2@gmail.com 12 | * Date: 2/4/15. 13 | */ 14 | public class AINetWorkerFieldProcessor implements AIAnnotationProcessor { 15 | @Override 16 | public void process(AIPresent present, Field field) throws Exception { 17 | field.setAccessible(true); 18 | field.set(present, NetInvoHandler.getWorker(field.getType())); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/field/AIPresenterFieldProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.field; 2 | 3 | import com.wangjie.androidbucket.mvp.*; 4 | import com.wangjie.androidinject.annotation.annotations.mvp.AIPresenter; 5 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 6 | import com.wangjie.androidinject.annotation.present.AIPresent; 7 | 8 | import java.lang.reflect.Field; 9 | 10 | /** 11 | * Author: wangjie 12 | * Email: tiantian.china.2@gmail.com 13 | * Date: 2/4/15. 14 | */ 15 | public class AIPresenterFieldProcessor implements AIAnnotationProcessor { 16 | @Override 17 | public void process(AIPresent present, Field field) throws Exception { 18 | field.setAccessible(true); 19 | 20 | AIPresenter aiPresenter = field.getAnnotation(AIPresenter.class); 21 | Class prClass = aiPresenter.presenter(); 22 | // Viewer层(Activity)中注入presenter 23 | ABBasePresenter presenter; 24 | if (ABNonePresenterImpl.class.equals(prClass)) { 25 | Class fieldType = field.getType(); 26 | if (ABBasePresenter.class.isAssignableFrom(fieldType)) { 27 | presenter = (ABBasePresenter) fieldType.newInstance(); 28 | } else { 29 | throw new Exception("presenter inject error!"); 30 | } 31 | } else { 32 | String presenterClazzName = prClass.getName(); 33 | presenter = (ABBasePresenter) Class.forName(presenterClazzName).newInstance(); 34 | } 35 | 36 | field.set(present, presenter); 37 | 38 | /** 39 | * 在presenter中注入viewer和interactor(presenter中需要有viewer和interactor的引用) 40 | */ 41 | // 把viewer注入到presenter中 42 | if (present instanceof ABActivityViewer) { 43 | presenter.setViewer((ABActivityViewer) present); 44 | } else { 45 | Field viewerField = present.getClass().getField("viewer"); 46 | viewerField.setAccessible(true); 47 | viewerField.set(presenter, present); 48 | } 49 | 50 | String interactorClazzName = aiPresenter.interactor().getName(); 51 | if (!ABNoneInteractorImpl.class.equals(aiPresenter.interactor())) { 52 | // 把interactor注入到presenter中 53 | ABInteractor interactor = (ABInteractor) Class.forName(interactorClazzName).newInstance(); 54 | presenter.setInteractor(interactor); 55 | } 56 | 57 | present.registerPresenter(presenter); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/field/AIScreenSizeFieldProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.field; 2 | 3 | import android.app.Activity; 4 | import android.graphics.Point; 5 | import android.os.Build; 6 | import android.view.Display; 7 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 8 | import com.wangjie.androidinject.annotation.present.AIPresent; 9 | 10 | import java.lang.reflect.Field; 11 | 12 | /** 13 | * Author: wangjie 14 | * Email: tiantian.china.2@gmail.com 15 | * Date: 2/4/15. 16 | */ 17 | public class AIScreenSizeFieldProcessor implements AIAnnotationProcessor { 18 | @Override 19 | public void process(AIPresent present, Field field) throws Exception { 20 | field.setAccessible(true); 21 | if (!Point.class.isAssignableFrom(field.getType())) { 22 | throw new Exception("field [" + field.getName() + "] must be a Point or its subclasses"); 23 | } 24 | Display display = ((Activity) present.getContext()).getWindowManager().getDefaultDisplay(); 25 | Point point = (Point) field.getType().newInstance(); 26 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { 27 | display.getSize(point); 28 | } else { 29 | point.set(display.getWidth(), display.getHeight()); 30 | } 31 | field.set(present, point); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/field/AISystemServiceFieldProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.field; 2 | 3 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 4 | import com.wangjie.androidinject.annotation.present.AIPresent; 5 | import com.wangjie.androidinject.annotation.util.SystemServiceUtil; 6 | 7 | import java.lang.reflect.Field; 8 | 9 | /** 10 | * Author: wangjie 11 | * Email: tiantian.china.2@gmail.com 12 | * Date: 2/4/15. 13 | */ 14 | public class AISystemServiceFieldProcessor implements AIAnnotationProcessor { 15 | @Override 16 | public void process(AIPresent present, Field field) throws Exception { 17 | field.setAccessible(true); 18 | field.set(present, SystemServiceUtil.getSystemServiceByClazz(present.getContext(), field.getType())); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/field/AIViewFieldProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.field; 2 | 3 | import android.content.res.Resources; 4 | import android.view.View; 5 | import android.widget.AdapterView; 6 | import com.wangjie.androidbucket.utils.ABTextUtil; 7 | import com.wangjie.androidinject.annotation.annotations.base.AIView; 8 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 9 | import com.wangjie.androidinject.annotation.listener.OnClickViewListener; 10 | import com.wangjie.androidinject.annotation.listener.OnItemClickViewListener; 11 | import com.wangjie.androidinject.annotation.listener.OnItemLongClickViewListener; 12 | import com.wangjie.androidinject.annotation.listener.OnLongClickViewListener; 13 | import com.wangjie.androidinject.annotation.present.AIPresent; 14 | 15 | import java.lang.reflect.Field; 16 | 17 | /** 18 | * Author: wangjie 19 | * Email: tiantian.china.2@gmail.com 20 | * Date: 2/4/15. 21 | */ 22 | public class AIViewFieldProcessor implements AIAnnotationProcessor { 23 | @Override 24 | public void process(AIPresent present, Field field) throws Exception { 25 | AIView aiView = field.getAnnotation(AIView.class); 26 | 27 | viewFindAnnotation(present, aiView, field); 28 | 29 | View view = (View) field.get(present); 30 | 31 | viewBindClick(present, aiView, view); 32 | 33 | viewBindLongClick(present, aiView, view); 34 | 35 | viewBindItemClick(present, aiView, view); 36 | 37 | viewBindItemLongClick(present, aiView, view); 38 | } 39 | 40 | /** 41 | * 绑定控件注解 42 | * 43 | * @param aiView 44 | * @param field 45 | * @throws Exception 46 | */ 47 | private void viewFindAnnotation(AIPresent present, AIView aiView, Field field) throws Exception { 48 | int viewId = aiView.value(); // 绑定控件注解 49 | // @AIView注解的value和id值均代表控件redId,如果之前的value是-1,则使用id值 50 | if (-1 == viewId) { 51 | viewId = aiView.id(); 52 | } 53 | 54 | if (-1 == viewId) { // 如果resId没有设置,则默认查找id名跟属性名相同的id 55 | Resources res = present.getContext().getResources(); 56 | viewId = res.getIdentifier(field.getName(), "id", present.getContext().getPackageName()); 57 | if (0 == viewId) { // 属性同名的id没有找到 58 | throw new Exception("no such identifier[R.id." + field.getName() + "] ! viewId: " + viewId); 59 | } 60 | } 61 | 62 | field.setAccessible(true); 63 | try { 64 | field.set(present, present.findViewById_(viewId)); 65 | } catch (Exception ex) { 66 | Exception injectEx = new Exception("Field[" + field.getName() + "] inject error!"); 67 | injectEx.setStackTrace(ex.getStackTrace()); 68 | throw injectEx; 69 | } 70 | 71 | } 72 | 73 | /** 74 | * 绑定控件点击事件注解 75 | * 76 | * @param aiView 77 | * @param view 78 | */ 79 | private void viewBindClick(AIPresent present, AIView aiView, View view) { 80 | String clickMethodName = aiView.clickMethod(); 81 | if (ABTextUtil.isBlank(clickMethodName)) { 82 | return; 83 | } 84 | view.setOnClickListener(OnClickViewListener.obtainListener(present, clickMethodName)); 85 | } 86 | 87 | /** 88 | * 绑定控件点击事件注解 89 | * 90 | * @param aiView 91 | * @param view 92 | */ 93 | private void viewBindLongClick(AIPresent present, AIView aiView, View view) { 94 | String longClickMethodName = aiView.longClickMethod(); 95 | if (ABTextUtil.isBlank(longClickMethodName)) { 96 | return; 97 | } 98 | view.setOnLongClickListener(OnLongClickViewListener.obtainListener(present, longClickMethodName)); 99 | } 100 | 101 | /** 102 | * 绑定控件item点击事件注解 103 | * 104 | * @param aiView 105 | * @param view 106 | */ 107 | private void viewBindItemClick(AIPresent present, AIView aiView, View view) throws Exception { 108 | // 如果view是AdapterView的子类(ListView, GridView, ExpandableListView...) 109 | String itemClickMethodName = aiView.itemClickMethod(); 110 | if (ABTextUtil.isBlank(itemClickMethodName)) { 111 | return; 112 | } 113 | 114 | if (AdapterView.class.isAssignableFrom(view.getClass())) { 115 | AdapterView adapterView = (AdapterView) view; 116 | adapterView.setOnItemClickListener(OnItemClickViewListener.obtainListener(present, itemClickMethodName)); 117 | } else { 118 | throw new Exception("view[" + view + "] is not AdapterView's subclass"); 119 | } 120 | 121 | } 122 | 123 | /** 124 | * 绑定控件item长按事件注解 125 | * 126 | * @param aiView 127 | * @param view 128 | */ 129 | private void viewBindItemLongClick(AIPresent present, AIView aiView, View view) throws Exception { 130 | // 如果view是AdapterView的子类(ListView, GridView, ExpandableListView...) 131 | String methodName = aiView.itemLongClickMethod(); 132 | if (ABTextUtil.isBlank(methodName)) { 133 | return; 134 | } 135 | 136 | if (AdapterView.class.isAssignableFrom(view.getClass())) { 137 | AdapterView adapterView = (AdapterView) view; 138 | adapterView.setOnItemLongClickListener(OnItemLongClickViewListener.obtainListener(present, methodName)); 139 | 140 | } else { 141 | throw new Exception("view[" + view + "] is not AdapterView's subclass"); 142 | } 143 | 144 | } 145 | 146 | 147 | } 148 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/method/AICheckedMethodProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.method; 2 | 3 | import android.widget.CompoundButton; 4 | import com.wangjie.androidinject.annotation.annotations.base.AIChecked; 5 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 6 | import com.wangjie.androidinject.annotation.listener.OnCheckChangedViewListener; 7 | import com.wangjie.androidinject.annotation.present.AIPresent; 8 | 9 | import java.lang.reflect.Method; 10 | 11 | /** 12 | * 绑定某方法设置所有控件的CheckedChange事件 13 | * Author: wangjie 14 | * Email: tiantian.china.2@gmail.com 15 | * Date: 2/4/15. 16 | */ 17 | public class AICheckedMethodProcessor implements AIAnnotationProcessor { 18 | @Override 19 | public void process(AIPresent present, Method method) throws Exception { 20 | AIChecked aiClick = method.getAnnotation(AIChecked.class); 21 | int[] ids = aiClick.value(); 22 | if (null == ids || ids.length <= 0) { 23 | throw new Exception("@AIChecked[" + method.getName() + "] value(ids) can not be empty!"); 24 | } 25 | for (int id : ids) { 26 | Object obj = present.findViewById_(id); 27 | if (null == obj) { 28 | throw new Exception("new such resource id[" + id + "]"); 29 | } 30 | if(!CompoundButton.class.isAssignableFrom(obj.getClass())){ 31 | throw new Exception("view[" + obj + "] is not CompoundButton's subclass"); 32 | } 33 | ((CompoundButton) obj).setOnCheckedChangeListener(OnCheckChangedViewListener.obtainListener(present, method.getName())); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/method/AIClickMethodProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.method; 2 | 3 | import android.view.View; 4 | import com.wangjie.androidinject.annotation.annotations.base.AIClick; 5 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 6 | import com.wangjie.androidinject.annotation.listener.OnClickViewListener; 7 | import com.wangjie.androidinject.annotation.present.AIPresent; 8 | 9 | import java.lang.reflect.Method; 10 | 11 | /** 12 | * 绑定某方法设置的所有控件的点击事件 13 | * Author: wangjie 14 | * Email: tiantian.china.2@gmail.com 15 | * Date: 2/4/15. 16 | */ 17 | public class AIClickMethodProcessor implements AIAnnotationProcessor { 18 | @Override 19 | public void process(AIPresent present, Method method) throws Exception { 20 | AIClick aiClick = method.getAnnotation(AIClick.class); 21 | int[] ids = aiClick.value(); 22 | if (null == ids || ids.length <= 0) { 23 | throw new Exception("@AIClick[" + method.getName() + "] value(ids) can not be empty!"); 24 | } 25 | for (int id : ids) { 26 | Object obj = present.findViewById_(id); 27 | if (null == obj) { 28 | throw new Exception("new such resource id[" + id + "]"); 29 | } 30 | if(!View.class.isAssignableFrom(obj.getClass())){ 31 | throw new Exception("view[" + obj + "] is not View's subclass"); 32 | } 33 | ((View) obj).setOnClickListener(OnClickViewListener.obtainListener(present, method.getName())); 34 | 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/method/AIItemClickMethodProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.method; 2 | 3 | import android.widget.AdapterView; 4 | import com.wangjie.androidinject.annotation.annotations.base.AIItemClick; 5 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 6 | import com.wangjie.androidinject.annotation.listener.OnItemClickViewListener; 7 | import com.wangjie.androidinject.annotation.present.AIPresent; 8 | 9 | import java.lang.reflect.Method; 10 | 11 | /** 12 | * 绑定某方法设置的所有控件的item点击事件 13 | * Author: wangjie 14 | * Email: tiantian.china.2@gmail.com 15 | * Date: 2/4/15. 16 | */ 17 | public class AIItemClickMethodProcessor implements AIAnnotationProcessor { 18 | @Override 19 | public void process(AIPresent present, Method method) throws Exception { 20 | AIItemClick aiItemClick = method.getAnnotation(AIItemClick.class); 21 | int[] ids = aiItemClick.value(); 22 | if (null == ids || ids.length <= 0) { 23 | throw new Exception("@AIItemClick[" + method.getName() + "] value(ids) can not be empty!"); 24 | } 25 | for (int id : ids) { 26 | Object obj = present.findViewById_(id); 27 | if (null == obj) { 28 | throw new Exception("new such resource id[" + id + "]"); 29 | } 30 | if (!AdapterView.class.isAssignableFrom(obj.getClass())) { 31 | throw new Exception("view[" + obj + "] is not AdapterView's subclass"); 32 | } 33 | AdapterView adapterView = (AdapterView) obj; 34 | if (!"".equals(method.getName())) { 35 | adapterView.setOnItemClickListener(OnItemClickViewListener.obtainListener(present, method.getName())); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/method/AIItemLongClickMethodProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.method; 2 | 3 | import android.widget.AdapterView; 4 | import com.wangjie.androidinject.annotation.annotations.base.AIItemLongClick; 5 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 6 | import com.wangjie.androidinject.annotation.listener.OnItemLongClickViewListener; 7 | import com.wangjie.androidinject.annotation.present.AIPresent; 8 | 9 | import java.lang.reflect.Method; 10 | 11 | /** 12 | * 绑定某方法设置的所有控件的item长按事件 13 | * Author: wangjie 14 | * Email: tiantian.china.2@gmail.com 15 | * Date: 2/4/15. 16 | */ 17 | public class AIItemLongClickMethodProcessor implements AIAnnotationProcessor { 18 | @Override 19 | public void process(AIPresent present, Method method) throws Exception { 20 | AIItemLongClick aiItemLongClick = method.getAnnotation(AIItemLongClick.class); 21 | int[] ids = aiItemLongClick.value(); 22 | if (null == ids || ids.length <= 0) { 23 | throw new Exception("@AIItemLongClick[" + method.getName() + "] value(ids) can not be empty!"); 24 | } 25 | for (int id : ids) { 26 | Object obj = present.findViewById_(id); 27 | if (null == obj) { 28 | throw new Exception("new such resource id[" + id + "]"); 29 | } 30 | if (!AdapterView.class.isAssignableFrom(obj.getClass())) { 31 | throw new Exception("view[" + obj + "] is not AdapterView's subclass"); 32 | } 33 | AdapterView adapterView = (AdapterView) obj; 34 | if (!"".equals(method.getName())) { 35 | adapterView.setOnItemLongClickListener(OnItemLongClickViewListener.obtainListener(present, method.getName())); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/method/AILongClickMethodProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.method; 2 | 3 | import android.view.View; 4 | import com.wangjie.androidinject.annotation.annotations.base.AILongClick; 5 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 6 | import com.wangjie.androidinject.annotation.listener.OnLongClickViewListener; 7 | import com.wangjie.androidinject.annotation.present.AIPresent; 8 | 9 | import java.lang.reflect.Method; 10 | 11 | /** 12 | * 绑定某方法设置的所有控件的长按事件 13 | * Author: wangjie 14 | * Email: tiantian.china.2@gmail.com 15 | * Date: 2/4/15. 16 | */ 17 | public class AILongClickMethodProcessor implements AIAnnotationProcessor { 18 | @Override 19 | public void process(AIPresent present, Method method) throws Exception { 20 | AILongClick aiLongClick = method.getAnnotation(AILongClick.class); 21 | int[] ids = aiLongClick.value(); 22 | if (null == ids || ids.length <= 0) { 23 | throw new Exception("@AILongClick[" + method.getName() + "] value(ids) can not be empty!"); 24 | } 25 | for (int id : ids) { 26 | Object obj = present.findViewById_(id); 27 | if (null == obj) { 28 | throw new Exception("new such resource id[" + id + "]"); 29 | } 30 | if(!View.class.isAssignableFrom(obj.getClass())){ 31 | throw new Exception("view[" + obj + "] is not View's subclass"); 32 | } 33 | ((View) obj).setOnLongClickListener(OnLongClickViewListener.obtainListener(present, method.getName())); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/type/AIFullScreenTypeProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.type; 2 | 3 | import android.app.Activity; 4 | import android.view.WindowManager; 5 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 6 | import com.wangjie.androidinject.annotation.present.AIPresent; 7 | 8 | /** 9 | * 实现全屏注解 10 | * Author: wangjie 11 | * Email: tiantian.china.2@gmail.com 12 | * Date: 2/4/15. 13 | */ 14 | public class AIFullScreenTypeProcessor implements AIAnnotationProcessor> { 15 | @Override 16 | public void process(AIPresent present, Class clazz) throws Exception { 17 | if (!Activity.class.isAssignableFrom(clazz)) { // 如果不是Activity 18 | throw new Exception(clazz.getName() + " is not Activity ! can not use @AIFullScreen Annotation. "); 19 | } 20 | 21 | // 设置Activity全屏 22 | ((Activity) present.getContext()).getWindow() 23 | .setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 24 | WindowManager.LayoutParams.FLAG_FULLSCREEN); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/type/AILayoutTypeProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.type; 2 | 3 | import android.support.v4.app.Fragment; 4 | import android.util.Log; 5 | import com.wangjie.androidinject.annotation.annotations.base.AILayout; 6 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 7 | import com.wangjie.androidinject.annotation.present.AIPresent; 8 | 9 | /** 10 | * 实现布局注解 11 | * Author: wangjie 12 | * Email: tiantian.china.2@gmail.com 13 | * Date: 2/4/15. 14 | */ 15 | public class AILayoutTypeProcessor implements AIAnnotationProcessor> { 16 | private static final String TAG = AILayoutTypeProcessor.class.getSimpleName(); 17 | 18 | @Override 19 | public void process(AIPresent present, Class clazz) throws Exception { 20 | // 如果是fragment,忽略这里的layout processor处理 21 | if (Fragment.class.isAssignableFrom(clazz) || android.app.Fragment.class.isAssignableFrom(clazz)) { 22 | Log.d(TAG, present.getClass() + " layout bind ignore in layout processor."); 23 | return; 24 | } 25 | 26 | // 布局类注解setContentView 27 | AILayout cv = clazz.getAnnotation(AILayout.class); 28 | if (null == cv) { 29 | throw new Exception("Present[" + present + "]had not added @AILayout annotation!"); 30 | } 31 | 32 | int layoutId = cv.value(); 33 | if (layoutId < 0) { 34 | throw new Exception("Present[" + present + "] @AILayout value layoutId is invalidate!"); 35 | } 36 | present.setContentView_(layoutId); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/base/process/type/AINoTitleTypeProcessor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.base.process.type; 2 | 3 | import android.app.Activity; 4 | import android.view.Window; 5 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 6 | import com.wangjie.androidinject.annotation.present.AIPresent; 7 | 8 | /** 9 | * 实现不显示title注解 10 | * Author: wangjie 11 | * Email: tiantian.china.2@gmail.com 12 | * Date: 2/4/15. 13 | */ 14 | public class AINoTitleTypeProcessor implements AIAnnotationProcessor> { 15 | @Override 16 | public void process(AIPresent present, Class clazz) throws Exception { 17 | if (!Activity.class.isAssignableFrom(clazz)) { // 如果不是Activity 18 | throw new Exception(clazz.getName() + " is not Activity ! can not use @AINoTitle Annotation. "); 19 | } 20 | 21 | // 设置不显示Title 22 | ((Activity) present.getContext()).requestWindowFeature(Window.FEATURE_NO_TITLE); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/net/AINetWork.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.net; 2 | 3 | import com.wangjie.androidbucket.log.Logger; 4 | import com.wangjie.androidbucket.utils.ABIOUtil; 5 | import org.apache.http.HttpEntity; 6 | import org.apache.http.HttpResponse; 7 | import org.apache.http.HttpVersion; 8 | import org.apache.http.client.HttpClient; 9 | import org.apache.http.client.entity.UrlEncodedFormEntity; 10 | import org.apache.http.client.methods.HttpDelete; 11 | import org.apache.http.client.methods.HttpGet; 12 | import org.apache.http.client.methods.HttpPost; 13 | import org.apache.http.conn.ClientConnectionManager; 14 | import org.apache.http.conn.scheme.PlainSocketFactory; 15 | import org.apache.http.conn.scheme.Scheme; 16 | import org.apache.http.conn.scheme.SchemeRegistry; 17 | import org.apache.http.conn.ssl.SSLSocketFactory; 18 | import org.apache.http.entity.StringEntity; 19 | import org.apache.http.impl.client.DefaultHttpClient; 20 | import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; 21 | import org.apache.http.message.BasicNameValuePair; 22 | import org.apache.http.params.BasicHttpParams; 23 | import org.apache.http.params.HttpConnectionParams; 24 | import org.apache.http.params.HttpParams; 25 | import org.apache.http.params.HttpProtocolParams; 26 | import org.apache.http.protocol.HTTP; 27 | 28 | import java.io.*; 29 | import java.security.KeyStore; 30 | import java.util.ArrayList; 31 | import java.util.List; 32 | import java.util.Map; 33 | import java.util.Set; 34 | import java.util.zip.GZIPInputStream; 35 | 36 | /** 37 | * @author wangjie 38 | * @version 创建时间:2013-3-9 上午9:29:40 39 | */ 40 | public class AINetWork { 41 | private static final String TAG = AINetWork.class.getSimpleName(); 42 | 43 | public static final String REQUEST_CONTENT_TYPE_JSON = "application/json"; 44 | 45 | /** 46 | * 使用post来请求url并返回StringBuilder对象 47 | * 48 | * @param map post携带的参数 49 | * @return 返回请求结果StringBuilder对象 50 | * @throws Exception 如果请求出错 51 | * @author wangjie 52 | */ 53 | 54 | public static StringBuilder postStringFromUrl(HttpClient httpClient, String baseUrl, 55 | Map map) throws IOException { 56 | return postStringFromUrl(httpClient, 20000, 20000, baseUrl, map); 57 | } 58 | 59 | public static StringBuilder postStringFromUrl(HttpClient httpClient, int connTimeout, int soTimeout, String baseUrl, 60 | Map map) throws IOException { 61 | if (null == httpClient) { 62 | httpClient = baseUrl.startsWith("https") ? getSSLHttpClient(connTimeout, soTimeout) : getDefaultHttpClient(connTimeout, soTimeout); 63 | } 64 | 65 | HttpPost httpPost = new HttpPost(baseUrl); 66 | httpPost.addHeader("Accept-Encoding", "gzip"); 67 | // 保持同一session 68 | // if(!"".equals(Variables.appCookie)){ 69 | // httpPost.setHeader("Cookie", "JSESSIONID=" + Variables.appCookie); 70 | // } 71 | 72 | List postData = new ArrayList(); 73 | if (null != map) { 74 | Set> entries = map.entrySet(); 75 | for (Map.Entry entry : entries) { 76 | postData.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); 77 | } 78 | } 79 | 80 | UrlEncodedFormEntity entity = new UrlEncodedFormEntity(postData, HTTP.UTF_8); 81 | httpPost.setEntity(entity); 82 | HttpResponse resp = httpClient.execute(httpPost); 83 | 84 | // CookieStore mCookieStore = httpClient.getCookieStore(); 85 | // // 更新session 86 | // List cookies = mCookieStore.getCookies(); 87 | // for (int i = 0; i < cookies.size(); i++) { 88 | // // 这里是读取Cookie['jsessionid']的值存在静态变量中,保证每次都是同一个值 89 | // if ("jsessionid".equalsIgnoreCase(cookies.get(i).getName())) { 90 | // Variables.appCookie = cookies.get(i).getValue(); 91 | // break; 92 | // } 93 | // } 94 | return obtainJsonStringFromGZIP(resp); 95 | // return obtainStringFromInputStream(resp.getRawEntity().getContent()); 96 | } 97 | 98 | 99 | /** 100 | * 使用get来请求url并返回StringBuilder对象 101 | * 102 | * @param baseUrl 103 | * @return 104 | * @throws Exception 105 | */ 106 | public static StringBuilder getStringFromUrl(HttpClient httpClient, String baseUrl) throws IOException { 107 | return getStringFromUrl(httpClient, 20000, 20000, baseUrl); 108 | } 109 | 110 | public static StringBuilder getStringFromUrl(HttpClient httpClient, int connTimeout, int soTimeout, String baseUrl) throws IOException { 111 | if (null == httpClient) { 112 | httpClient = baseUrl.startsWith("https") ? getSSLHttpClient(connTimeout, soTimeout) : getDefaultHttpClient(connTimeout, soTimeout); 113 | } 114 | 115 | HttpGet httpGet = new HttpGet(baseUrl); 116 | httpGet.addHeader("Accept-Encoding", "gzip"); 117 | HttpResponse httpResponse; 118 | HttpEntity httpEntity; 119 | //生成一个http客户端对象 120 | 121 | //使用Http客户端发送请求对象,得到服务器发回的响应httpResponse 122 | httpResponse = httpClient.execute(httpGet); 123 | // //httpEntity中有服务器发回的响应的内容 124 | // httpEntity = httpResponse.getRawEntity(); 125 | // return obtainStringFromInputStream(httpEntity.getContent()); 126 | return obtainJsonStringFromGZIP(httpResponse); 127 | 128 | } 129 | 130 | 131 | public static StringBuilder deleteStringFromUrl(HttpClient httpClient, String baseUrl) throws IOException { 132 | return deleteStringFromUrl(httpClient, 20000, 20000, baseUrl); 133 | } 134 | 135 | public static StringBuilder deleteStringFromUrl(HttpClient httpClient, int connTimeout, int soTimeout, String baseUrl) throws IOException { 136 | if (null == httpClient) { 137 | httpClient = baseUrl.startsWith("https") ? getSSLHttpClient(connTimeout, soTimeout) : getDefaultHttpClient(connTimeout, soTimeout); 138 | } 139 | HttpDelete httpDelete = new HttpDelete(baseUrl); 140 | httpDelete.addHeader("Accept-Encoding", "gzip"); 141 | HttpResponse httpResponse; 142 | HttpEntity httpEntity; 143 | //生成一个http客户端对象 144 | 145 | //使用Http客户端发送请求对象,得到服务器发回的响应httpResponse 146 | httpResponse = httpClient.execute(httpDelete); 147 | // //httpEntity中有服务器发回的响应的内容 148 | // httpEntity = httpResponse.getRawEntity(); 149 | // return obtainStringFromInputStream(httpEntity.getContent()); 150 | return obtainJsonStringFromGZIP(httpResponse); 151 | 152 | } 153 | 154 | 155 | public static HttpClient getDefaultHttpClient(int connTimeout, int soTimeout) { 156 | HttpClient httpClient = new DefaultHttpClient(); 157 | HttpParams params = httpClient.getParams(); 158 | HttpConnectionParams.setConnectionTimeout(params, connTimeout); 159 | HttpConnectionParams.setSoTimeout(params, soTimeout); 160 | return httpClient; 161 | } 162 | 163 | public static interface OnSSLHttpClientSchemeRegister { 164 | public Scheme getConfigScheme(); 165 | } 166 | 167 | private static OnSSLHttpClientSchemeRegister onSSLHttpClientSchemeRegister; 168 | 169 | public static OnSSLHttpClientSchemeRegister getOnSSLHttpClientSchemeRegister() { 170 | return onSSLHttpClientSchemeRegister; 171 | } 172 | 173 | public static void setOnSSLHttpClientSchemeRegister(OnSSLHttpClientSchemeRegister onSSLHttpClientSchemeRegister) { 174 | AINetWork.onSSLHttpClientSchemeRegister = onSSLHttpClientSchemeRegister; 175 | } 176 | 177 | public static HttpClient getSSLHttpClient(int connTimeout, int soTimeout) { 178 | try { 179 | KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 180 | trustStore.load(null, null); 181 | 182 | SSLSocketFactory sf = new SSLSocketFactoryEx(trustStore); 183 | sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 184 | 185 | HttpParams params = new BasicHttpParams(); 186 | 187 | HttpConnectionParams.setConnectionTimeout(params, connTimeout); 188 | HttpConnectionParams.setSoTimeout(params, soTimeout); 189 | 190 | HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 191 | HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); 192 | 193 | 194 | SchemeRegistry registry = new SchemeRegistry(); 195 | registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 196 | registry.register(new Scheme("https", sf, 443)); 197 | // registry.register(new Scheme("https", sf, 9094)); 198 | // registry.register(new Scheme("https", sf, 9000)); 199 | // registry.register(new Scheme("https", PlainSocketFactory.getSocketFactory(), 80)); 200 | Scheme scheme; 201 | if (null != onSSLHttpClientSchemeRegister 202 | && null != (scheme = onSSLHttpClientSchemeRegister.getConfigScheme())) { 203 | registry.register(scheme); 204 | } 205 | 206 | ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); 207 | 208 | return new DefaultHttpClient(ccm, params); 209 | } catch (Exception e) { 210 | Logger.e(TAG, e); 211 | return new DefaultHttpClient(); 212 | } 213 | } 214 | 215 | private static StringBuilder obtainJsonStringFromGZIP(HttpResponse response) { 216 | StringBuilder resultSb = null; 217 | InputStream is = null; 218 | BufferedInputStream bis = null; 219 | InputStreamReader reader = null; 220 | try { 221 | is = response.getEntity().getContent(); 222 | bis = new BufferedInputStream(is); 223 | bis.mark(2); 224 | // 取前两个字节 225 | byte[] header = new byte[2]; 226 | int result = bis.read(header); 227 | // reset输入流到开始位置 228 | bis.reset(); 229 | // 判断是否是GZIP格式 230 | int headerData = getShort(header); 231 | // Gzip 流 的前两个字节是 0x1f8b 232 | if (result != -1 && headerData == 0x1f8b) { 233 | is = new GZIPInputStream(bis); 234 | } else { 235 | is = bis; 236 | } 237 | reader = new InputStreamReader(is, "utf-8"); 238 | char[] data = new char[100]; 239 | int readSize; 240 | resultSb = new StringBuilder(); 241 | while ((readSize = reader.read(data)) > 0) { 242 | resultSb.append(data, 0, readSize); 243 | } 244 | } catch (Exception e) { 245 | Logger.e(TAG, e); 246 | } finally { 247 | ABIOUtil.closeIO(is, bis, reader); 248 | } 249 | return resultSb; 250 | } 251 | 252 | private static int getShort(byte[] data) { 253 | return (int) ((data[0] << 8) | data[1] & 0xFF); 254 | } 255 | 256 | 257 | /** 258 | * 通过InputStream获得字符串。 259 | * 260 | * @param is 需要进行读取的InputStream对象 261 | * @return 返回读取后的字符串信息 262 | * @author wangjie 263 | */ 264 | public static StringBuilder obtainStringFromInputStream(InputStream is) { 265 | StringBuilder sb = new StringBuilder(); 266 | BufferedReader br = null; 267 | br = new BufferedReader(new InputStreamReader(is)); 268 | String line = null; 269 | try { 270 | while (null != (line = br.readLine())) { 271 | sb.append(line); 272 | } 273 | } catch (Exception e) { 274 | e.printStackTrace(); 275 | } finally { 276 | try { 277 | br.close(); 278 | } catch (Exception e) { 279 | e.printStackTrace(); 280 | } 281 | } 282 | return sb; 283 | } 284 | 285 | 286 | } 287 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/net/NetInvoHandler.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.net; 2 | 3 | import android.text.TextUtils; 4 | import com.google.gson.GsonBuilder; 5 | import com.wangjie.androidbucket.log.Logger; 6 | import com.wangjie.androidbucket.services.network.http.ABHttpMethod; 7 | import com.wangjie.androidbucket.services.network.http.ABHttpUtil; 8 | import com.wangjie.androidbucket.services.network.http.HttpAccessParameter; 9 | import com.wangjie.androidbucket.utils.ABTextUtil; 10 | import com.wangjie.androidinject.annotation.annotations.net.*; 11 | import com.wangjie.androidinject.annotation.util.Params; 12 | import org.apache.http.HttpEntity; 13 | import org.apache.http.NameValuePair; 14 | import org.apache.http.client.utils.URLEncodedUtils; 15 | import org.apache.http.message.BasicNameValuePair; 16 | import org.apache.http.protocol.HTTP; 17 | 18 | import java.lang.annotation.Annotation; 19 | import java.lang.reflect.InvocationHandler; 20 | import java.lang.reflect.Method; 21 | import java.lang.reflect.Proxy; 22 | import java.lang.reflect.Type; 23 | import java.util.HashMap; 24 | 25 | /** 26 | * Created with IntelliJ IDEA. Author: wangjie email:tiantian.china.2@gmail.com 27 | * Date: 14-2-7 Time: 下午1:40 28 | */ 29 | public class NetInvoHandler implements InvocationHandler { 30 | 31 | private static final String TAG = NetInvoHandler.class.getSimpleName(); 32 | 33 | private static HashMap, NetInvoHandler> invoHandlers = new HashMap, NetInvoHandler>(); 34 | 35 | private Object proxy; // 代理对象 36 | 37 | public synchronized static T getWorker(Class clazz) { 38 | NetInvoHandler netInvoHandler = invoHandlers.get(clazz); 39 | if (null == netInvoHandler) { 40 | netInvoHandler = new NetInvoHandler(); 41 | netInvoHandler.setProxy(Proxy.newProxyInstance( 42 | clazz.getClassLoader(), new Class[]{clazz}, 43 | netInvoHandler)); 44 | invoHandlers.put(clazz, netInvoHandler); 45 | } 46 | return (T) netInvoHandler.getProxy(); 47 | } 48 | 49 | @Override 50 | public Object invoke(Object proxy, Method method, Object[] args) 51 | throws Throwable { 52 | args = null == args ? new Object[0] : args; 53 | 54 | String domain = null; 55 | Class[] inters = proxy.getClass().getInterfaces(); 56 | if (null == inters || inters.length <= 0) { 57 | Logger.e(TAG, "Invalid NetWorker Proxy Object!!"); 58 | domain = ""; 59 | } else { 60 | Class interClazz = inters[0]; 61 | domain = interClazz.isAnnotationPresent(AIMapper.class) ? interClazz.getAnnotation(AIMapper.class).value() : ""; 62 | } 63 | 64 | try { 65 | // get请求(非上传文件) 66 | if (method.isAnnotationPresent(AIGet.class)) { 67 | return getHttpGetResponse(method, args, domain); 68 | } 69 | 70 | // delete请求(非上传文件) 71 | if (method.isAnnotationPresent(AIDelete.class)) { 72 | return getHttpDeleteResponse(method, args, domain); 73 | } 74 | 75 | 76 | // post请求(非上传文件) 77 | if (method.isAnnotationPresent(AIPost.class)) { 78 | return getHttpPostResponse(method, args, domain); 79 | } 80 | 81 | if (method.isAnnotationPresent(AIRaw.class)) { 82 | return getHttpRawResponse(method, args, domain); 83 | } 84 | 85 | } catch (Exception ex) { 86 | Logger.e(TAG, "invoke error: ", ex); 87 | throw ex; 88 | } 89 | return null; 90 | } 91 | 92 | private Object getHttpDeleteResponse(Method method, Object[] args, String domain) throws Exception { 93 | AIDelete aiDelete = method.getAnnotation(AIDelete.class); 94 | String url = domain + aiDelete.value(); 95 | if (TextUtils.isEmpty(url)) { 96 | throw new Exception("net work [" + method.getName() 97 | + "]@AIDelete value()[url] is empty!!"); 98 | } 99 | Annotation[][] annotations = method.getParameterAnnotations(); 100 | for (int i = 0; i < args.length; i++) { 101 | url = generateUrl(args, url, annotations, i, args[i]); 102 | 103 | } 104 | 105 | Logger.d(TAG, "Delete url[" + method.getName() + "]: " + url); 106 | 107 | aiDelete.sessionEnable(); 108 | 109 | String result = ABHttpUtil.getHttpResponse( 110 | new HttpAccessParameter() 111 | .setMethod(ABHttpMethod.DELETE) 112 | .setWebApi(url) 113 | .setSessionEnableMethod(aiDelete.sessionEnable()) 114 | ); 115 | if (null == result) { 116 | return null; 117 | } 118 | Type returnType = method.getGenericReturnType(); 119 | return generateReturnValue(returnType, result); 120 | } 121 | 122 | /** 123 | * 获取HttpRaw返回反射AIRaw注解结果 124 | * 125 | * @param method Worker声明的方法 126 | * @param args Worker声明方法参数 127 | * @param domain Http Domain 128 | * @return 返回请求后反射解析结果 129 | * @throws Exception 130 | */ 131 | private Object getHttpRawResponse(Method method, Object[] args, String domain) throws Exception { 132 | AIRaw aiRaw = method.getAnnotation(AIRaw.class); 133 | String url = domain + aiRaw.value(); 134 | if (TextUtils.isEmpty(url)) { 135 | throw new Exception("net work [" + method.getName() 136 | + "]@AIRaw value()[url] is empty!!"); 137 | } 138 | // Object entity; 139 | if (ABTextUtil.isEmpty(args)) { 140 | throw new Exception(String.format("Please declare at least a HttpEntity in parameter list for method [%s]!!!", method.getName())); 141 | } 142 | 143 | HttpEntity httpEntity = null; 144 | Annotation[][] annotations = method.getParameterAnnotations(); 145 | for (int i = 0; i < args.length; i++) { 146 | Object arg = args[i]; 147 | 148 | // 根据参数生成URL 149 | if (!HttpEntity.class.isAssignableFrom(arg.getClass())) { 150 | url = generateUrl(args, url, annotations, i, arg); 151 | } else { // 如果是HttpEntity则转换为HttpEntity 152 | if (null != httpEntity) { 153 | throw new Exception(String.format("Only one HttpEntity allowed in parameter list for method [%s]!!!", method.getName())); 154 | } 155 | httpEntity = (HttpEntity) arg; 156 | } 157 | } 158 | if (null == httpEntity) { 159 | throw new Exception(String.format("Please declare HttpEntity in parameter list for method [%s]!!!", method.getName())); 160 | } 161 | 162 | String contentType = aiRaw.contentType(); 163 | 164 | HttpAccessParameter accessParameter = new HttpAccessParameter() 165 | .setMethod(ABHttpMethod.POST) 166 | .setWebApi(url) 167 | .setRawEntity(httpEntity) 168 | .setSessionEnableMethod(aiRaw.sessionEnable()); 169 | 170 | if (!ABTextUtil.isEmpty(contentType)) { 171 | accessParameter.setHeadNameValuePairs(new BasicNameValuePair(HTTP.CONTENT_TYPE, contentType)); 172 | } 173 | 174 | // 获取 175 | String result = ABHttpUtil.getHttpResponse(accessParameter); 176 | if (null == result) { 177 | return null; 178 | } 179 | Type returnType = method.getGenericReturnType(); 180 | return generateReturnValue(returnType, result); 181 | } 182 | 183 | 184 | /** 185 | * 生成URL 186 | * 187 | * @param args 188 | * @param url 189 | * @param annotations 190 | * @param i 191 | * @param arg 192 | * @return 193 | */ 194 | private String generateUrl(Object[] args, String url, Annotation[][] annotations, int i, Object arg) { 195 | if (Params.class.isAssignableFrom(arg.getClass())) { // 如果属性为Params,则追加在后面 196 | url = appendParamsAfterUrl(url, (Params) arg); 197 | } else { // 如果属性添加了@AIParam注解,则替换链接中#{xxx} 198 | String repName = ((AIParam) annotations[i][0]).value(); 199 | url = url.replace("#{" + repName + "}", args[i] + ""); 200 | } 201 | return url; 202 | } 203 | 204 | /** 205 | * 获取HttpGet返回反射AIPost注解结果 206 | * 207 | * @param method Worker声明的方法 208 | * @param args Worker声明方法参数 209 | * @param domain Http Domain 210 | * @return 返回请求后反射解析结果 211 | * @throws Exception 212 | */ 213 | private Object getHttpPostResponse(Method method, Object[] args, String domain) throws Exception { 214 | AIPost aiPost = method.getAnnotation(AIPost.class); 215 | String url = domain + aiPost.value(); 216 | if (TextUtils.isEmpty(url)) { 217 | throw new Exception("net work [" + method.getName() 218 | + "]@AIPost value()[url] is empty!!"); 219 | } 220 | Annotation[][] annotations = method.getParameterAnnotations(); 221 | Params map = new Params(); 222 | for (int i = 0; i < args.length; i++) { 223 | if (Params.class.isAssignableFrom(args[i].getClass())) { // 如果属性为Params,则追加在后面 224 | map.putAll((Params) args[i]); 225 | } else { 226 | String repName = ((AIParam) annotations[i][0]).value(); 227 | if (url.contains("#{" + repName + "}")) { 228 | url = url.replace("#{" + repName + "}", args[i] + ""); 229 | } else { 230 | map.add(repName, args[i] + ""); 231 | } 232 | 233 | } 234 | 235 | } 236 | 237 | // 打印log 238 | logUrlInfo(url, map); 239 | 240 | String result = ABHttpUtil.getHttpResponse( 241 | new HttpAccessParameter() 242 | .setMethod(ABHttpMethod.POST) 243 | .setWebApi(url) 244 | .setParamNameValuePairs(map.getNameValuePairs()) 245 | .setSessionEnableMethod(aiPost.sessionEnable()) 246 | ); 247 | if (null == result) { 248 | return null; 249 | } 250 | Type returnType = method.getGenericReturnType(); 251 | return generateReturnValue(returnType, result); 252 | } 253 | 254 | /** 255 | * 获取HttpGet返回反射AIGet注解结果 256 | * 257 | * @param method Worker声明的方法 258 | * @param args Worker声明方法参数 259 | * @param domain Http Domain 260 | * @return 反射AIGet注解结果 261 | * @throws Exception 262 | */ 263 | private Object getHttpGetResponse(Method method, Object[] args, String domain) throws Exception { 264 | AIGet aiGet = method.getAnnotation(AIGet.class); 265 | String url = domain + aiGet.value(); 266 | if (TextUtils.isEmpty(url)) { 267 | throw new Exception("net work [" + method.getName() 268 | + "]@AIGet value()[url] is empty!!"); 269 | } 270 | Annotation[][] annotations = method.getParameterAnnotations(); 271 | for (int i = 0; i < args.length; i++) { 272 | url = generateUrl(args, url, annotations, i, args[i]); 273 | 274 | } 275 | 276 | Logger.d(TAG, "GET url[" + method.getName() + "]: " + url); 277 | 278 | aiGet.sessionEnable(); 279 | 280 | String result = ABHttpUtil.getHttpResponse( 281 | new HttpAccessParameter() 282 | .setMethod(ABHttpMethod.GET) 283 | .setWebApi(url) 284 | .setSessionEnableMethod(aiGet.sessionEnable()) 285 | ); 286 | if (null == result) { 287 | return null; 288 | } 289 | Type returnType = method.getGenericReturnType(); 290 | return generateReturnValue(returnType, result); 291 | } 292 | 293 | 294 | /** 295 | * 通过返回的类型和请求的结果,生产返回值 296 | * 297 | * @param returnType 298 | * @param str 299 | * @return 300 | */ 301 | private Object generateReturnValue(Type returnType, String str) { 302 | if (Void.TYPE == returnType) { 303 | return null; 304 | } 305 | if (String.class == returnType) { 306 | return str; 307 | } 308 | 309 | return new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss:SSS").create().fromJson(str, returnType); 310 | } 311 | 312 | /** 313 | * 打印log,便于调试 314 | * 315 | * @param url 316 | * @param params 317 | */ 318 | private void logUrlInfo(String url, Params params) { 319 | if (!Logger.debug && !Logger.logFile) { 320 | return; 321 | } 322 | StringBuilder sb = new StringBuilder(); 323 | for (NameValuePair pair : params.getNameValuePairs()) { 324 | sb.append(", ").append(pair.getName()).append("=").append(pair.getValue()); 325 | } 326 | Logger.d(TAG, url + "?" + (ABTextUtil.isEmpty(sb) ? "" : sb.toString().substring(1))); 327 | } 328 | 329 | public Object getProxy() { 330 | return proxy; 331 | } 332 | 333 | public void setProxy(Object proxy) { 334 | this.proxy = proxy; 335 | } 336 | 337 | private String appendParamsAfterUrl(String url, Params params) { 338 | if (null == params || ABTextUtil.isEmpty(params.getNameValuePairs())) { 339 | return url; 340 | } 341 | url = url.endsWith("?") ? url : url + "?"; 342 | return url + URLEncodedUtils.format(params.getNameValuePairs(), "utf-8"); 343 | } 344 | 345 | } 346 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/net/RetMessage.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.net; 2 | 3 | import com.google.gson.GsonBuilder; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Json响应结果包装类 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email:tiantian.china.2@gmail.com 11 | * Date: 14-2-7 12 | * Time: 下午4:25 13 | */ 14 | public class RetMessage { 15 | 16 | private int resultCode; // 结果码,必须包含 17 | 18 | private List list; // 返回的数据 19 | 20 | private T obj; // 返回的数据 21 | 22 | private Integer size; // 返回数据长度 23 | 24 | private String errorMessage; // 返回错误信息 25 | 26 | public String toJson() { 27 | return new GsonBuilder() 28 | .setDateFormat("yyyy-MM-dd HH:mm:ss:SSS") 29 | .create() 30 | .toJson(this); 31 | } 32 | 33 | public int getResultCode() { 34 | return resultCode; 35 | } 36 | 37 | public RetMessage setResultCode(int resultCode) { 38 | this.resultCode = resultCode; 39 | return this; 40 | } 41 | 42 | public List getList() { 43 | return list; 44 | } 45 | 46 | public RetMessage setList(List list) { 47 | this.list = list; 48 | if (null != this.list) { 49 | this.size = this.list.size(); 50 | } 51 | return this; 52 | } 53 | 54 | public T getObj() { 55 | return obj; 56 | } 57 | 58 | public RetMessage setObj(T obj) { 59 | this.obj = obj; 60 | return this; 61 | } 62 | 63 | public Integer getSize() { 64 | return size; 65 | } 66 | 67 | public RetMessage setSize(Integer size) { 68 | this.size = size; 69 | return this; 70 | } 71 | 72 | public String getErrorMessage() { 73 | return errorMessage; 74 | } 75 | 76 | public RetMessage setErrorMessage(String errorMessage) { 77 | this.errorMessage = errorMessage; 78 | return this; 79 | } 80 | 81 | 82 | } 83 | 84 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/net/SSLSocketFactoryEx.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.net; 2 | 3 | import org.apache.http.conn.ssl.SSLSocketFactory; 4 | 5 | import javax.net.ssl.SSLContext; 6 | import javax.net.ssl.TrustManager; 7 | import javax.net.ssl.X509TrustManager; 8 | import java.io.IOException; 9 | import java.net.Socket; 10 | import java.net.UnknownHostException; 11 | import java.security.*; 12 | 13 | /** 14 | * 15 | */ 16 | public class SSLSocketFactoryEx extends SSLSocketFactory { 17 | 18 | SSLContext sslContext = SSLContext.getInstance("TLS"); 19 | 20 | public SSLSocketFactoryEx(KeyStore truststore) 21 | throws NoSuchAlgorithmException, KeyManagementException, 22 | KeyStoreException, UnrecoverableKeyException { 23 | super(truststore); 24 | 25 | TrustManager tm = new X509TrustManager() { 26 | 27 | public java.security.cert.X509Certificate[] getAcceptedIssuers() { 28 | return null; 29 | } 30 | 31 | @Override 32 | public void checkClientTrusted( 33 | java.security.cert.X509Certificate[] chain, String authType) 34 | throws java.security.cert.CertificateException { 35 | 36 | } 37 | 38 | @Override 39 | public void checkServerTrusted( 40 | java.security.cert.X509Certificate[] chain, String authType) 41 | throws java.security.cert.CertificateException { 42 | 43 | } 44 | }; 45 | 46 | sslContext.init(null, new TrustManager[]{tm}, null); 47 | } 48 | 49 | @Override 50 | public Socket createSocket(Socket socket, String host, int port, 51 | boolean autoClose) throws IOException { 52 | return sslContext.getSocketFactory().createSocket(socket, host, port, 53 | autoClose); 54 | } 55 | 56 | @Override 57 | public Socket createSocket() throws IOException { 58 | return sslContext.getSocketFactory().createSocket(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/orm/AIDatabaseHelper.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.orm; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteDatabase.CursorFactory; 6 | import android.database.sqlite.SQLiteOpenHelper; 7 | 8 | public class AIDatabaseHelper extends SQLiteOpenHelper { 9 | // private static final int VERSION = 1; 10 | 11 | // private static final String TAG = AIDatabaseHelper.class.getSimpleName(); 12 | 13 | // 在SQLiteOpenHelper子类中必须调用该构造函数 14 | public AIDatabaseHelper(Context context, String name, CursorFactory factory, 15 | int version) { 16 | super(context, name, factory, version); 17 | } 18 | 19 | public AIDatabaseHelper(Context context, String name, int version) { 20 | this(context, name, null, version); 21 | } 22 | 23 | // public AIDatabaseHelper(Context context, String name) { 24 | // this(context, name, 1); 25 | // } 26 | 27 | // 该函数是在第一次创建数据库时执行,实际上是在第一次得到SQLiteOpenHelper对象的时候才会调用这个方法 28 | @Override 29 | public void onCreate(SQLiteDatabase db) { 30 | 31 | } 32 | 33 | @Override 34 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 35 | 36 | } 37 | 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/orm/AIDbExecutor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.orm; 2 | 3 | import android.content.Context; 4 | import android.database.Cursor; 5 | import android.database.sqlite.SQLiteDatabase; 6 | import com.wangjie.androidbucket.log.Logger; 7 | import com.wangjie.androidinject.annotation.annotations.orm.AIColumn; 8 | import com.wangjie.androidinject.annotation.annotations.orm.AIPrimaryKey; 9 | import com.wangjie.androidinject.annotation.annotations.orm.AITable; 10 | import com.wangjie.androidinject.annotation.util.AITextUtil; 11 | import com.wangjie.androidbucket.utils.ReflectionUtils; 12 | 13 | import java.lang.reflect.Field; 14 | import java.sql.Blob; 15 | import java.util.*; 16 | 17 | /** 18 | * Created with IntelliJ IDEA. 19 | * Author: wangjie email:tiantian.china.2@gmail.com 20 | * Date: 14-3-24 21 | * Time: 下午4:44 22 | */ 23 | public abstract class AIDbExecutor { 24 | private static final String TAG = AIDbExecutor.class.getSimpleName(); 25 | // public SQLiteDatabase db; 26 | public AIDatabaseHelper dbHelper; 27 | 28 | public Context context; 29 | 30 | public AIDbExecutor(Context context) { 31 | this.context = context; 32 | this.dbHelper = obtainDbHelper(); 33 | } 34 | 35 | public abstract AIDatabaseHelper obtainDbHelper(); 36 | 37 | /** 38 | * 查询数据库表并自动装箱到clazz对象中 39 | * @param sql 40 | * @param clazz 41 | * @return 42 | * @throws Exception 43 | */ 44 | public List executeQuery(String sql, String[] selectionArgs, Class clazz) throws Exception{ 45 | SQLiteDatabase db = null; 46 | Cursor cursor = null; 47 | try{ 48 | sql = sql.trim(); 49 | if(null == sql || !sql.toLowerCase().contains("select")){ 50 | throw new Exception("paramter sql is not a SELECT statement!"); 51 | } 52 | db = dbHelper.getReadableDatabase(); 53 | cursor = db.rawQuery(sql, selectionArgs); 54 | 55 | Logger.d(TAG, "[executeQuery]sql ==> " + sql); 56 | Logger.d(TAG, "[executeQuery]params ==> " + AITextUtil.joinArray(selectionArgs, ", ")); 57 | List list = null; 58 | while(cursor.moveToNext()){ 59 | @SuppressWarnings("unchecked") 60 | final T obj = (T)clazz.newInstance(); 61 | final Cursor cur = cursor; 62 | ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() { 63 | 64 | public void doWith(Field field) throws Exception { 65 | String columnValue = getColumnValue(field); 66 | if (null == columnValue) { // 如果该属性没有加column注解 67 | return; 68 | } 69 | field.setAccessible(true); 70 | int index = cur.getColumnIndex(columnValue); 71 | Class fieldType = field.getType(); 72 | String fieldTypeName = fieldType.getName(); 73 | if(String.class == fieldType){ 74 | field.set(obj, cur.getString(index)); 75 | }else if(Long.class == fieldType || fieldTypeName.equals("long")){ 76 | field.set(obj, cur.getLong(index)); 77 | }else if(Integer.class == fieldType || fieldTypeName.equals("int")){ 78 | field.set(obj, cur.getInt(index)); 79 | }else if(Short.class == fieldType || fieldTypeName.equals("short")){ 80 | field.set(obj, cur.getShort(index)); 81 | }else if(Double.class == fieldType || fieldTypeName.equals("double")){ 82 | field.set(obj, cur.getDouble(index)); 83 | }else if(Float.class == fieldType || fieldTypeName.equals("float")){ 84 | field.set(obj, cur.getFloat(index)); 85 | }else if(Blob.class == fieldType){ 86 | field.set(obj, cur.getBlob(index)); 87 | }else{ 88 | field.set(obj, null); 89 | } 90 | } 91 | 92 | }); 93 | if(null == list){ 94 | list = new ArrayList(); 95 | } 96 | list.add(obj); 97 | 98 | } 99 | Logger.d(TAG, "[executeQuery]result: " + list); 100 | return list; 101 | }catch(Exception ex){ 102 | throw ex; 103 | }finally{ 104 | closeCursor(cursor); 105 | closeDatabase(db); 106 | } 107 | 108 | } 109 | 110 | 111 | /** 112 | * 插入一条数据 113 | * @param obj 114 | * @return 115 | * @throws Exception 116 | */ 117 | public synchronized int executeSave(final T obj) throws Exception{ 118 | SQLiteDatabase db = null; 119 | try{ 120 | final Map map = new HashMap(); 121 | ReflectionUtils.doWithFields(obj.getClass(), new ReflectionUtils.FieldCallback() { 122 | 123 | public void doWith(Field field) throws Exception 124 | { 125 | String columnValue = getColumnValue(field); 126 | if(null == columnValue){ // 如果该属性没有加column注解,则不插入数据库 127 | return; 128 | } 129 | AIPrimaryKey pk = field.getAnnotation(AIPrimaryKey.class); 130 | if(null != pk && !pk.insertable()){ // 如果是主键,并且设置为不需插入,则不插入数据库 131 | return; 132 | } 133 | field.setAccessible(true); 134 | map.put(columnValue, field.get(obj)); 135 | } 136 | }); 137 | 138 | String tablename = getTableValue(obj.getClass()); // 获取表名 139 | 140 | String sql = "insert into " + tablename + "(" + AITextUtil.joinStrings(map.keySet(), ",") + ")" + " values(" + AITextUtil.generatePlaceholders(map.size()) + ")"; 141 | 142 | db = dbHelper.getWritableDatabase(); 143 | Logger.d(TAG, "[executeSave]sql ==> " + sql); 144 | db.execSQL(sql, map.values().toArray()); 145 | int result = 0; 146 | Logger.d(TAG, "[executeSave]result ==> " + result); 147 | return result; 148 | }catch(Exception ex){ 149 | throw ex; 150 | }finally{ 151 | closeDatabase(db); 152 | } 153 | 154 | } 155 | 156 | 157 | /** 158 | * 根据主键更新数据 159 | * 如果包括是null,则范围是不在排除中的 160 | * 如果包括不是null,则范围是在包括并且不再排除中的 161 | * @param obj 162 | * @param includeParams 包含哪些字段需要更新数据(类的属性) 163 | * @param excludeParams 排除哪些字段不更新数据(类的属性) 164 | * @return 165 | * @throws Exception 166 | */ 167 | public synchronized int executeUpdate(final T obj, final String[] includeParams, final String[] excludeParams) throws Exception{ 168 | SQLiteDatabase db = null; 169 | try{ 170 | final List includeParamsList = null == includeParams ? null : Arrays.asList(includeParams); 171 | final List excludeParamsList = null == excludeParams ? new ArrayList() : Arrays.asList(excludeParams); 172 | 173 | final Map pkMap = new HashMap(); // 存储主键的属性和值(类中使用Primay Key注解的) 174 | final Map updateMap = new HashMap(); // 存储需要更新的属性和值 175 | ReflectionUtils.doWithFields(obj.getClass(), new ReflectionUtils.FieldCallback() { 176 | 177 | public void doWith(Field field) throws Exception 178 | { 179 | String columnValue = getColumnValue(field); 180 | if(null == columnValue){ // 如果该属性没有加column注解,则不插入数据库 181 | return; 182 | } 183 | AIPrimaryKey primaryKey = field.getAnnotation(AIPrimaryKey.class); 184 | if(null == primaryKey){ // 如果不是主键 185 | if(shouldModifyField(field, includeParamsList, excludeParamsList)){ // 如果包含在includeParams中,并不包含在excludeParams中,则需要更新这个字段 186 | field.setAccessible(true); 187 | updateMap.put(columnValue, field.get(obj)); 188 | } 189 | return; 190 | } 191 | //如果是主键 192 | field.setAccessible(true); 193 | pkMap.put(columnValue, field.get(obj)); 194 | 195 | } 196 | }); 197 | 198 | if(updateMap.size() <= 0 || pkMap.size() <= 0){ 199 | Logger.w(TAG, "[executeUpdate]更新数据失败,无需更新任何字段或未指定主键而无法更新数据"); 200 | return -1; 201 | } 202 | 203 | String tablename = getTableValue(obj.getClass()); // 获取表名 204 | 205 | String updateStr = AITextUtil.joinStrings(updateMap.keySet(), ",", "=?"); 206 | // String pkStr = AITextUtil.joinStrings(pkMap.keySet(), ",", "=?"); 207 | String pkStr = AITextUtil.joinStrings(pkMap.keySet(), " and ", "=?"); 208 | String sql = "update " + tablename + " set " + updateStr + " where (" + pkStr + ")"; 209 | Logger.d(TAG, "==> [executeUpdate]sql: " + sql); 210 | 211 | db = dbHelper.getWritableDatabase(); 212 | 213 | List args = new ArrayList(); 214 | args.addAll(updateMap.values()); 215 | args.addAll(pkMap.values()); 216 | db.execSQL(sql, args.toArray()); 217 | Logger.d(TAG, "[executeUpdate]result success "); 218 | return 0; 219 | }catch(Exception ex){ 220 | throw ex; 221 | }finally{ 222 | closeDatabase(db); 223 | } 224 | } 225 | 226 | 227 | 228 | /** 229 | * 根据主键删除数据 230 | * @param obj 231 | * @return 232 | * @throws Exception 233 | */ 234 | public synchronized int executeDelete(final T obj) throws Exception{ 235 | SQLiteDatabase db = null; 236 | try{ 237 | final Map pkMap = new HashMap(); // 存储主键的属性和值(类中使用Primay Key注解的) 238 | ReflectionUtils.doWithFields(obj.getClass(), new ReflectionUtils.FieldCallback() { 239 | 240 | public void doWith(Field field) throws Exception 241 | { 242 | String columnValue = getColumnValue(field); 243 | if(null == columnValue){ // 如果该属性没有加column注解,则不插入数据库 244 | return; 245 | } 246 | AIPrimaryKey primaryKey = field.getAnnotation(AIPrimaryKey.class); 247 | if(null == primaryKey){ // 如果不是主键 248 | return; 249 | } 250 | //如果是主键 251 | field.setAccessible(true); 252 | pkMap.put(columnValue, field.get(obj)); 253 | 254 | } 255 | }); 256 | 257 | String tablename = getTableValue(obj.getClass()); // 获取表名 258 | 259 | String pkStr = AITextUtil.joinStrings(pkMap.keySet(), ",", "=?"); 260 | String sql = "delete from " + tablename + " where " + pkStr; 261 | Logger.d(TAG, "==> [executeDelete]sql: " + sql); 262 | 263 | db = dbHelper.getWritableDatabase(); 264 | 265 | db.execSQL(sql, pkMap.values().toArray()); 266 | 267 | Logger.d(TAG, "[executeDelete]result ==> "); 268 | return 0; 269 | }catch(Exception ex){ 270 | throw ex; 271 | }finally{ 272 | closeDatabase(db); 273 | } 274 | } 275 | 276 | /** 277 | * 如果不存在,则保存;如果存在,则更新 278 | * @param obj 279 | */ 280 | public synchronized void executeSaveOrUpdate(T obj) throws Exception{ 281 | if(isExist(obj)){ 282 | executeUpdate(obj, null, null); 283 | }else{ 284 | executeSave(obj); 285 | } 286 | } 287 | 288 | /** 289 | * 如果不存在,则保存;如果存在,则不处理 290 | * @param obj 291 | * @throws Exception 292 | */ 293 | public synchronized void executeSaveIfNotExist(T obj) throws Exception{ 294 | if(!isExist(obj)){ 295 | executeSave(obj); 296 | } 297 | } 298 | 299 | /** 300 | * 查询是否存在 301 | * @param obj 302 | * @return 303 | */ 304 | public boolean isExist(final T obj){ 305 | SQLiteDatabase db = null; 306 | Cursor cursor = null; 307 | try{ 308 | String tablename = getTableValue(obj.getClass()); // 获取表名 309 | 310 | Map pkMap = getPkWhereCase(obj); 311 | String pkStr = AITextUtil.joinStrings(pkMap.keySet(), " and ", "=?"); 312 | 313 | String sql = "select count(*) from " + tablename + " where (" + pkStr + ")"; 314 | Logger.d(TAG, "==> [isExist]sql: " + sql); 315 | 316 | db = dbHelper.getWritableDatabase(); 317 | 318 | String[] strings = new String[pkMap.values().size()]; 319 | cursor = db.rawQuery(sql, pkMap.values().toArray(strings)); 320 | 321 | if(null != cursor && cursor.moveToFirst()){ 322 | int count = cursor.getInt(0); 323 | return count > 0; 324 | } 325 | 326 | }catch(Exception ex){ 327 | Logger.e(TAG, ex); 328 | }finally { 329 | closeCursor(cursor); 330 | closeDatabase(db); 331 | } 332 | return false; 333 | } 334 | 335 | private Map getPkWhereCase(final T obj){ 336 | final Map pkMap = new HashMap(); // 存储主键的属性和值(类中使用Primay Key注解的) 337 | ReflectionUtils.doWithFields(obj.getClass(), new ReflectionUtils.FieldCallback() { 338 | 339 | public void doWith(Field field) throws Exception 340 | { 341 | String columnValue = getColumnValue(field); 342 | if(null == columnValue){ // 如果该属性没有加column注解,则不插入数据库 343 | return; 344 | } 345 | AIPrimaryKey primaryKey = field.getAnnotation(AIPrimaryKey.class); 346 | if(null == primaryKey){ // 如果不是主键 347 | return; 348 | } 349 | //如果是主键 350 | field.setAccessible(true); 351 | pkMap.put(columnValue, field.get(obj)); 352 | 353 | } 354 | }); 355 | 356 | return pkMap; 357 | } 358 | 359 | 360 | /** 361 | * 执行一条sql语句 362 | * @param sql 363 | * @param selectionArgs 364 | * @throws Exception 365 | */ 366 | public void executeSql(String sql, Object[] selectionArgs) throws Exception{ 367 | SQLiteDatabase db = null; 368 | try{ 369 | db = dbHelper.getWritableDatabase(); 370 | db.execSQL(sql, selectionArgs); 371 | }catch(Exception ex){ 372 | throw ex; 373 | }finally { 374 | closeDatabase(db); 375 | } 376 | } 377 | 378 | /** 379 | * 执行删除 380 | * @param clazz 381 | * @param whereClause 382 | * @param whereArgs 383 | * @return 384 | * @throws Exception 385 | */ 386 | public synchronized int executeDelete(Class clazz, String whereClause, String[] whereArgs) throws Exception{ 387 | SQLiteDatabase db = null; 388 | try{ 389 | db = dbHelper.getWritableDatabase(); 390 | return db.delete(getTableValue(clazz), whereClause, whereArgs); 391 | }catch(Exception ex){ 392 | throw ex; 393 | }finally { 394 | closeDatabase(db); 395 | } 396 | } 397 | 398 | /** 399 | * 使用事务执行多条sql 400 | * @param sqlCases 401 | * @throws Exception 402 | */ 403 | public void executeSqlTransaction(AISqlCase... sqlCases) throws Exception{ 404 | if(null == sqlCases || sqlCases.length <= 0){ 405 | return; 406 | } 407 | SQLiteDatabase db = null; 408 | try{ 409 | db = dbHelper.getWritableDatabase(); 410 | db.beginTransaction(); 411 | for(AISqlCase sc : sqlCases){ 412 | db.execSQL(sc.getSql(), sc.getSelectionArgs()); 413 | } 414 | db.setTransactionSuccessful(); 415 | }catch(Exception ex){ 416 | throw ex; 417 | }finally { 418 | if(null != db){ 419 | db.endTransaction(); 420 | closeDatabase(db); 421 | } 422 | } 423 | 424 | } 425 | 426 | 427 | public AIDatabaseHelper getDbHelper(){ 428 | return dbHelper; 429 | } 430 | 431 | public SQLiteDatabase getReadableDatabase(){ 432 | return dbHelper.getReadableDatabase(); 433 | } 434 | public SQLiteDatabase getWritableDatabase(){ 435 | return dbHelper.getWritableDatabase(); 436 | } 437 | 438 | 439 | 440 | 441 | /** 442 | * 判断更新数据时是否需要修改某个字段 443 | * 如果包括是null,则范围是不在排除中的 444 | * 如果包括不是null,则范围是在包括并且不再排除中的 445 | * @param field 446 | * @param includeParamsList 447 | * @param excludeParamsList 448 | * @return 449 | */ 450 | private boolean shouldModifyField(Field field, List includeParamsList, List excludeParamsList){ 451 | String fieldname = field.getName(); 452 | if(null == includeParamsList){ 453 | return !excludeParamsList.contains(fieldname); 454 | } 455 | return includeParamsList.contains(fieldname) && !excludeParamsList.contains(fieldname); 456 | } 457 | 458 | 459 | /** 460 | * 获得Column对应的value值(表的列名) 461 | * @param field 462 | * @return 如果该属性没有加column注解,则返回null;如果该属性的column注解value为空,则使用属性名(全小写)作为列名;否则使用value值 463 | */ 464 | private String getColumnValue(Field field){ 465 | AIColumn column = field.getAnnotation(AIColumn.class); 466 | if(null == column){ // 如果该属性没有加column注解,则返回null 467 | return null; 468 | } 469 | String value = column.value(); 470 | if("".equals(value)){ // 如果该属性的column注解value为空,则使用属性名 471 | return field.getName().toLowerCase(); 472 | } 473 | return value; 474 | } 475 | /** 476 | * 获得Table对应的value值(表名) 477 | * @param clazz 478 | * @return 如果类中没有加Table注解,或者Table注解为空,那么直接使用类名(全小写)作为表名;否则使用value值 479 | */ 480 | private String getTableValue(Class clazz){ 481 | AITable table = clazz.getAnnotation(AITable.class); 482 | if(null == table || "".equals(table.value())){ // 如果类中没有加Table注解,或者Table注解为空,那么直接使用类名作为表名 483 | return clazz.getSimpleName().toLowerCase(); 484 | } 485 | return table.value(); 486 | } 487 | 488 | 489 | public void closeCursor(Cursor cursor){ 490 | if(null == cursor){ 491 | return; 492 | } 493 | cursor.close(); 494 | } 495 | 496 | public void closeDatabase(SQLiteDatabase db){ 497 | if(null == db){ 498 | return; 499 | } 500 | db.close(); 501 | } 502 | 503 | 504 | } 505 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/core/orm/AISqlCase.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.core.orm; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * Author: wangjie email:tiantian.china.2@gmail.com 6 | * Date: 14-3-25 7 | * Time: 下午3:15 8 | */ 9 | public class AISqlCase { 10 | private String sql; 11 | private Object[] selectionArgs; 12 | 13 | public AISqlCase() { 14 | } 15 | 16 | public AISqlCase(String sql, Object[] selectionArgs) { 17 | this.sql = sql; 18 | this.selectionArgs = selectionArgs; 19 | } 20 | 21 | public String getSql() { 22 | return sql; 23 | } 24 | 25 | public void setSql(String sql) { 26 | this.sql = sql; 27 | } 28 | 29 | public Object[] getSelectionArgs() { 30 | return selectionArgs; 31 | } 32 | 33 | public void setSelectionArgs(Object[] selectionArgs) { 34 | this.selectionArgs = selectionArgs; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/exception/AIBaseException.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.exception; 2 | 3 | /** 4 | * Author: wangjie 5 | * Email: tiantian.china.2@gmail.com 6 | * Date: 6/19/15. 7 | */ 8 | public class AIBaseException extends Exception{ 9 | public AIBaseException() { 10 | } 11 | 12 | public AIBaseException(String detailMessage) { 13 | super(detailMessage); 14 | } 15 | 16 | public AIBaseException(String detailMessage, Throwable throwable) { 17 | super(detailMessage, throwable); 18 | } 19 | 20 | public AIBaseException(Throwable throwable) { 21 | super(throwable); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/exception/AINoSuchAnnotationProcessorException.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.exception; 2 | 3 | /** 4 | * Author: wangjie 5 | * Email: tiantian.china.2@gmail.com 6 | * Date: 6/19/15. 7 | */ 8 | public class AINoSuchAnnotationProcessorException extends AIBaseException{ 9 | public AINoSuchAnnotationProcessorException() { 10 | } 11 | 12 | public AINoSuchAnnotationProcessorException(String detailMessage) { 13 | super(detailMessage); 14 | } 15 | 16 | public AINoSuchAnnotationProcessorException(String detailMessage, Throwable throwable) { 17 | super(detailMessage, throwable); 18 | } 19 | 20 | public AINoSuchAnnotationProcessorException(Throwable throwable) { 21 | super(throwable); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/listener/OnCheckChangedViewListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.listener; 2 | 3 | import android.util.Log; 4 | import android.view.View; 5 | import android.widget.CompoundButton; 6 | import com.wangjie.androidinject.annotation.present.AIPresent; 7 | 8 | import java.lang.reflect.Method; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * Created with IntelliJ IDEA. 14 | * Author: wangjie email: tiantian.china.2@gmail.com 15 | * Date: 13-11-29 16 | * Time: 下午4:01 17 | */ 18 | public class OnCheckChangedViewListener implements CompoundButton.OnCheckedChangeListener{ 19 | private static Map listeners = new HashMap(); 20 | 21 | public synchronized static OnCheckChangedViewListener obtainListener(AIPresent present, String clickMethodName){ 22 | String identifier = present.toString() + "_" + clickMethodName; 23 | OnCheckChangedViewListener listener = listeners.get(identifier); 24 | if(null == listener){ 25 | listener = new OnCheckChangedViewListener(present, clickMethodName); 26 | listeners.put(identifier, listener); 27 | } 28 | return listener; 29 | } 30 | 31 | private static final String TAG = OnCheckChangedViewListener.class.getSimpleName(); 32 | private AIPresent present; 33 | private String callbackMethodName; 34 | 35 | private OnCheckChangedViewListener(AIPresent present, String callbackMethodName) { 36 | this.present = present; 37 | this.callbackMethodName = callbackMethodName; 38 | } 39 | 40 | @Override 41 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 42 | try { 43 | Method callbackMethod = present.getClass().getDeclaredMethod(callbackMethodName, CompoundButton.class, boolean.class); 44 | callbackMethod.setAccessible(true); 45 | callbackMethod.invoke(present, buttonView, isChecked); 46 | } catch (Exception e) { 47 | Log.e(TAG, "e: ", e); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/listener/OnClickViewListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.listener; 2 | 3 | import android.view.View; 4 | import com.wangjie.androidbucket.log.Logger; 5 | import com.wangjie.androidinject.annotation.present.AIPresent; 6 | 7 | import java.lang.reflect.Method; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * Author: wangjie email: tiantian.china.2@gmail.com 14 | * Date: 13-11-29 15 | * Time: 下午4:01 16 | */ 17 | public class OnClickViewListener implements View.OnClickListener { 18 | private static Map listeners = new HashMap(); 19 | 20 | public synchronized static OnClickViewListener obtainListener(AIPresent present, String clickMethodName) { 21 | String identifier = present.toString() + "_" + clickMethodName; 22 | OnClickViewListener onClickViewListener = listeners.get(identifier); 23 | if (null == onClickViewListener) { 24 | onClickViewListener = new OnClickViewListener(present, clickMethodName); 25 | listeners.put(identifier, onClickViewListener); 26 | } 27 | return onClickViewListener; 28 | } 29 | 30 | private static final String TAG = OnClickViewListener.class.getSimpleName(); 31 | private AIPresent present; 32 | private String callbackMethodName; 33 | 34 | private OnClickViewListener(AIPresent present, String callbackMethodName) { 35 | this.present = present; 36 | this.callbackMethodName = callbackMethodName; 37 | } 38 | 39 | @Override 40 | public void onClick(View v) { 41 | try { 42 | Method callbackMethod = present.getClass().getDeclaredMethod(callbackMethodName, View.class); 43 | callbackMethod.setAccessible(true); 44 | callbackMethod.invoke(present, v); 45 | } catch (Exception e) { 46 | e.printStackTrace(); 47 | Logger.e(TAG, "e: ", e); 48 | } 49 | 50 | } 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/listener/OnItemClickViewListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.listener; 2 | 3 | import android.util.Log; 4 | import android.view.View; 5 | import android.widget.AdapterView; 6 | import com.wangjie.androidinject.annotation.present.AIPresent; 7 | 8 | import java.lang.reflect.Method; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * Created with IntelliJ IDEA. 14 | * Author: wangjie email: tiantian.china.2@gmail.com 15 | * Date: 13-11-29 16 | * Time: 下午4:01 17 | */ 18 | public class OnItemClickViewListener implements AdapterView.OnItemClickListener{ 19 | private static Map listeners = new HashMap(); 20 | 21 | public synchronized static OnItemClickViewListener obtainListener(AIPresent present, String clickMethodName){ 22 | String identifier = present.toString() + "_" + clickMethodName; 23 | OnItemClickViewListener onItemClickViewListener = listeners.get(identifier); 24 | if(null == onItemClickViewListener){ 25 | onItemClickViewListener = new OnItemClickViewListener(present, clickMethodName); 26 | listeners.put(identifier, onItemClickViewListener); 27 | } 28 | return onItemClickViewListener; 29 | } 30 | 31 | private static final String TAG = OnItemClickViewListener.class.getSimpleName(); 32 | private AIPresent present; 33 | private String callbackMethodName; 34 | 35 | private OnItemClickViewListener(AIPresent present, String callbackMethodName) { 36 | this.present = present; 37 | this.callbackMethodName = callbackMethodName; 38 | } 39 | 40 | 41 | @Override 42 | public void onItemClick(AdapterView parent, View view, int position, long id) { 43 | try { 44 | Method callbackMethod = present.getClass().getDeclaredMethod(callbackMethodName, AdapterView.class, View.class, int.class, long.class); 45 | callbackMethod.setAccessible(true); 46 | callbackMethod.invoke(present, parent, view, position, id); 47 | } catch (Exception e) { 48 | e.printStackTrace(); 49 | Log.e(TAG, "e: ", e); 50 | } 51 | } 52 | 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/listener/OnItemLongClickViewListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.listener; 2 | 3 | import android.util.Log; 4 | import android.view.View; 5 | import android.widget.AdapterView; 6 | import com.wangjie.androidinject.annotation.present.AIPresent; 7 | 8 | import java.lang.reflect.Method; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * Created with IntelliJ IDEA. 14 | * Author: wangjie email: tiantian.china.2@gmail.com 15 | * Date: 13-11-29 16 | * Time: 下午4:01 17 | */ 18 | public class OnItemLongClickViewListener implements AdapterView.OnItemLongClickListener{ 19 | private static Map listeners = new HashMap(); 20 | 21 | public synchronized static OnItemLongClickViewListener obtainListener(AIPresent present, String clickMethodName){ 22 | String identifier = present.toString() + "_" + clickMethodName; 23 | OnItemLongClickViewListener onItemLongClickViewListener = listeners.get(identifier); 24 | if(null == onItemLongClickViewListener){ 25 | onItemLongClickViewListener = new OnItemLongClickViewListener(present, clickMethodName); 26 | listeners.put(identifier, onItemLongClickViewListener); 27 | } 28 | return onItemLongClickViewListener; 29 | } 30 | 31 | private static final String TAG = OnItemLongClickViewListener.class.getSimpleName(); 32 | private AIPresent present; 33 | private String callbackMethodName; 34 | 35 | private OnItemLongClickViewListener(AIPresent present, String callbackMethodName) { 36 | this.present = present; 37 | this.callbackMethodName = callbackMethodName; 38 | } 39 | 40 | 41 | @Override 42 | public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { 43 | Boolean result = true; 44 | try { 45 | Method callbackMethod = present.getClass().getDeclaredMethod(callbackMethodName, AdapterView.class, View.class, int.class, long.class); 46 | callbackMethod.setAccessible(true); 47 | Object obj = callbackMethod.invoke(present, adapterView, view, i, l); 48 | if(obj instanceof Boolean){ 49 | result = (Boolean)obj; 50 | } 51 | } catch (Exception e) { 52 | e.printStackTrace(); 53 | Log.e(TAG, "e: ", e); 54 | } 55 | return result; 56 | } 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/listener/OnLongClickViewListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.listener; 2 | 3 | import android.util.Log; 4 | import android.view.View; 5 | import com.wangjie.androidinject.annotation.present.AIPresent; 6 | 7 | import java.lang.reflect.Method; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * Author: wangjie email: tiantian.china.2@gmail.com 14 | * Date: 13-11-29 15 | * Time: 下午4:01 16 | */ 17 | public class OnLongClickViewListener implements View.OnLongClickListener{ 18 | private static Map listeners = new HashMap(); 19 | 20 | public synchronized static OnLongClickViewListener obtainListener(AIPresent present, String clickMethodName){ 21 | String identifier = present.toString() + "_" + clickMethodName; 22 | OnLongClickViewListener onClickViewListener = listeners.get(identifier); 23 | if(null == onClickViewListener){ 24 | onClickViewListener = new OnLongClickViewListener(present, clickMethodName); 25 | listeners.put(identifier, onClickViewListener); 26 | } 27 | return onClickViewListener; 28 | } 29 | 30 | private static final String TAG = OnLongClickViewListener.class.getSimpleName(); 31 | private AIPresent present; 32 | private String callbackMethodName; 33 | 34 | private OnLongClickViewListener(AIPresent present, String callbackMethodName) { 35 | this.present = present; 36 | this.callbackMethodName = callbackMethodName; 37 | } 38 | 39 | @Override 40 | public boolean onLongClick(View v) { 41 | Boolean result = true; 42 | try { 43 | Method callbackMethod = present.getClass().getDeclaredMethod(callbackMethodName, View.class); 44 | callbackMethod.setAccessible(true); 45 | Object obj = callbackMethod.invoke(present, v); 46 | if(obj instanceof Boolean){ 47 | result = (Boolean)obj; 48 | } 49 | } catch (Exception e) { 50 | e.printStackTrace(); 51 | Log.e(TAG, "e: ", e); 52 | } 53 | return result; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/present/AIActionBarActivity.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.present; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.widget.AdapterView; 8 | import android.widget.CompoundButton; 9 | import com.wangjie.androidbucket.log.Logger; 10 | import com.wangjie.androidbucket.present.ABActionBarActivity; 11 | import com.wangjie.androidinject.annotation.core.base.AnnotationManager; 12 | import com.wangjie.androidinject.annotation.present.common.CallbackSample; 13 | 14 | import java.lang.reflect.Field; 15 | import java.lang.reflect.Method; 16 | 17 | /** 18 | * Created with IntelliJ IDEA. 19 | * Author: wangjie email: tiantian.china.2@gmail.com 20 | * Date: 13-11-29 21 | * Time: 下午2:02 22 | */ 23 | /** 24 | * @deprecated Use {@link com.wangjie.androidinject.annotation.present.AIAppCompatActivity} instead. 25 | */ 26 | @Deprecated 27 | public class AIActionBarActivity extends ABActionBarActivity implements AIPresent, CallbackSample { 28 | private static final String TAG = AIActionBarActivity.class.getSimpleName(); 29 | public Context context; 30 | public Class clazz; 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | long start = System.currentTimeMillis(); 34 | super.onCreate(savedInstanceState); 35 | context = this; 36 | clazz = ((Object)this).getClass(); 37 | // clazz = AIActivity.class; 38 | try { 39 | new AnnotationManager(this).initAnnotations(); 40 | } catch (Exception e) { 41 | onInjectFailed(e); 42 | } 43 | Log.d(TAG, "[" + clazz.getSimpleName() + "]onCreate supper(parser annotations) takes: " + (System.currentTimeMillis() - start) + "ms"); 44 | } 45 | 46 | 47 | @Override 48 | public void onInjectFailed(Exception exception) { 49 | Logger.e(TAG, "inject failed!!: ", exception); 50 | } 51 | 52 | @Override 53 | public Context getContext() { 54 | return context; 55 | } 56 | 57 | @Override 58 | public void setContentView_(int layoutResID) { 59 | setContentView(layoutResID); 60 | } 61 | 62 | @Override 63 | public View findViewById_(int resId) { 64 | return findViewById(resId); 65 | } 66 | 67 | 68 | @Override 69 | public void parserTypeAnnotations(Class clazz) throws Exception {} 70 | @Override 71 | public void parserMethodAnnotations(Method method) throws Exception {} 72 | @Override 73 | public void parserFieldAnnotations(Field field) throws Exception {} 74 | 75 | @Override 76 | public void onClickCallbackSample(View view) {} 77 | @Override 78 | public void onLongClickCallbackSample(View view) {} 79 | @Override 80 | public void onItemClickCallbackSample(AdapterView parent, View view, int position, long id) {} 81 | @Override 82 | public void onItemLongClickCallbackSample(AdapterView parent, View view, int position, long id) {} 83 | @Override 84 | public void onCheckedChangedCallbackSample(CompoundButton buttonView, boolean isChecked) {} 85 | 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/present/AIActivity.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.present; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.widget.AdapterView; 8 | import android.widget.CompoundButton; 9 | import com.wangjie.androidbucket.log.Logger; 10 | import com.wangjie.androidbucket.present.ABActivity; 11 | import com.wangjie.androidinject.annotation.core.base.AnnotationManager; 12 | import com.wangjie.androidinject.annotation.present.common.CallbackSample; 13 | 14 | import java.lang.reflect.Field; 15 | import java.lang.reflect.Method; 16 | 17 | /** 18 | * Created with IntelliJ IDEA. 19 | * Author: wangjie email: tiantian.china.2@gmail.com 20 | * Date: 13-11-29 21 | * Time: 下午2:02 22 | */ 23 | /** 24 | * @deprecated Use {@link com.wangjie.androidinject.annotation.present.AIAppCompatActivity} instead. 25 | */ 26 | @Deprecated 27 | public class AIActivity extends ABActivity implements AIPresent, CallbackSample { 28 | private static final String TAG = AIActivity.class.getSimpleName(); 29 | public Context context; 30 | public Class clazz; 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | long start = System.currentTimeMillis(); 34 | super.onCreate(savedInstanceState); 35 | context = this; 36 | clazz = ((Object)this).getClass(); 37 | // clazz = AIActivity.class; 38 | try { 39 | new AnnotationManager(this).initAnnotations(); 40 | } catch (Exception e) { 41 | onInjectFailed(e); 42 | } 43 | Log.d(TAG, "[" + clazz.getSimpleName() + "]onCreate supper(parser annotations) takes: " + (System.currentTimeMillis() - start) + "ms"); 44 | } 45 | 46 | @Override 47 | public void onInjectFailed(Exception exception) { 48 | Logger.e(TAG, "inject failed!!: ", exception); 49 | } 50 | 51 | @Override 52 | public Context getContext() { 53 | return context; 54 | } 55 | 56 | @Override 57 | public void setContentView_(int layoutResID) { 58 | setContentView(layoutResID); 59 | } 60 | 61 | @Override 62 | public View findViewById_(int resId) { 63 | return findViewById(resId); 64 | } 65 | 66 | @Override 67 | public void parserTypeAnnotations(Class clazz) throws Exception {} 68 | @Override 69 | public void parserMethodAnnotations(Method method) throws Exception {} 70 | @Override 71 | public void parserFieldAnnotations(Field field) throws Exception {} 72 | 73 | @Override 74 | public void onClickCallbackSample(View view) {} 75 | @Override 76 | public void onLongClickCallbackSample(View view) {} 77 | @Override 78 | public void onItemClickCallbackSample(AdapterView parent, View view, int position, long id) {} 79 | @Override 80 | public void onItemLongClickCallbackSample(AdapterView parent, View view, int position, long id) {} 81 | @Override 82 | public void onCheckedChangedCallbackSample(CompoundButton buttonView, boolean isChecked) {} 83 | 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/present/AIAppCompatActivity.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.present; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.widget.AdapterView; 8 | import android.widget.CompoundButton; 9 | import com.wangjie.androidbucket.log.Logger; 10 | import com.wangjie.androidbucket.present.ABAppCompatActivity; 11 | import com.wangjie.androidinject.annotation.core.base.AnnotationManager; 12 | import com.wangjie.androidinject.annotation.present.common.CallbackSample; 13 | 14 | import java.lang.reflect.Field; 15 | import java.lang.reflect.Method; 16 | 17 | /** 18 | * Author: wangjie 19 | * Email: tiantian.china.2@gmail.com 20 | * Date: 6/10/15. 21 | */ 22 | public class AIAppCompatActivity extends ABAppCompatActivity implements AIPresent, CallbackSample { 23 | private static final String TAG = AIAppCompatActivity.class.getSimpleName(); 24 | public Context context; 25 | public Class clazz; 26 | 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | long start = System.currentTimeMillis(); 30 | super.onCreate(savedInstanceState); 31 | context = this; 32 | clazz = ((Object) this).getClass(); 33 | // clazz = AIActivity.class; 34 | try { 35 | new AnnotationManager(this).initAnnotations(); 36 | } catch (Exception e) { 37 | onInjectFailed(e); 38 | } 39 | Log.d(TAG, "[" + clazz.getSimpleName() + "]onCreate supper(parser annotations) takes: " + (System.currentTimeMillis() - start) + "ms"); 40 | } 41 | 42 | 43 | @Override 44 | public void onInjectFailed(Exception exception) { 45 | Logger.e(TAG, "inject failed!!: ", exception); 46 | } 47 | 48 | @Override 49 | public Context getContext() { 50 | return context; 51 | } 52 | 53 | @Override 54 | public void setContentView_(int layoutResID) { 55 | setContentView(layoutResID); 56 | } 57 | 58 | @Override 59 | public View findViewById_(int resId) { 60 | return findViewById(resId); 61 | } 62 | 63 | 64 | @Override 65 | public void parserTypeAnnotations(Class clazz) throws Exception { 66 | } 67 | 68 | @Override 69 | public void parserMethodAnnotations(Method method) throws Exception { 70 | } 71 | 72 | @Override 73 | public void parserFieldAnnotations(Field field) throws Exception { 74 | } 75 | 76 | @Override 77 | public void onClickCallbackSample(View view) { 78 | } 79 | 80 | @Override 81 | public void onLongClickCallbackSample(View view) { 82 | } 83 | 84 | @Override 85 | public void onItemClickCallbackSample(AdapterView parent, View view, int position, long id) { 86 | } 87 | 88 | @Override 89 | public void onItemLongClickCallbackSample(AdapterView parent, View view, int position, long id) { 90 | } 91 | 92 | @Override 93 | public void onCheckedChangedCallbackSample(CompoundButton buttonView, boolean isChecked) { 94 | } 95 | 96 | 97 | } -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/present/AIFragment.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.present; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import android.util.Log; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.AdapterView; 11 | import android.widget.CompoundButton; 12 | import com.wangjie.androidbucket.log.Logger; 13 | import com.wangjie.androidbucket.present.ABFragment; 14 | import com.wangjie.androidinject.annotation.core.base.AnnotationManager; 15 | import com.wangjie.androidinject.annotation.core.base.ParticularAnnotation; 16 | import com.wangjie.androidinject.annotation.present.common.CallbackSample; 17 | 18 | import java.lang.reflect.Field; 19 | import java.lang.reflect.Method; 20 | 21 | /** 22 | * Created with IntelliJ IDEA. 23 | * Author: wangjie email: tiantian.china.2@gmail.com 24 | * Date: 13-12-4 25 | * Time: 下午4:37 26 | */ 27 | @Deprecated 28 | public class AIFragment extends ABFragment implements AIPresent, CallbackSample{ 29 | private static String TAG = AIFragment.class.getSimpleName(); 30 | public Context context; 31 | public Class clazz; 32 | @Override 33 | public void onAttach(Activity activity) { 34 | super.onAttach(activity); 35 | } 36 | 37 | @Override 38 | public void onCreate(Bundle savedInstanceState) { 39 | super.onCreate(savedInstanceState); 40 | context = this.getActivity(); 41 | clazz = ((Object)this).getClass(); 42 | } 43 | 44 | @Override 45 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 46 | return ParticularAnnotation.realizeLayoutAnnotation(this, inflater, container); 47 | } 48 | 49 | @Override 50 | public void onActivityCreated(Bundle savedInstanceState) { 51 | long start = System.currentTimeMillis(); 52 | super.onActivityCreated(savedInstanceState); 53 | try { 54 | new AnnotationManager(this).initAnnotations(); 55 | } catch (Exception e) { 56 | onInjectFailed(e); 57 | } 58 | Log.d(TAG, "[" + clazz.getSimpleName() + "]onActivityCreated supper(parser annotations) takes: " + (System.currentTimeMillis() - start) + "ms"); 59 | } 60 | 61 | // @Override 62 | // public void onStart() { 63 | // super.onStart(); 64 | // } 65 | // 66 | // @Override 67 | // public void onResume() { 68 | // super.onResume(); 69 | // } 70 | // 71 | // @Override 72 | // public void onPause() { 73 | // super.onPause(); 74 | // } 75 | // 76 | // @Override 77 | // public void onStop() { 78 | // super.onStop(); 79 | // } 80 | // 81 | // @Override 82 | // public void onDestroyView() { 83 | // super.onDestroyView(); 84 | // } 85 | // 86 | // @Override 87 | // public void onDestroy() { 88 | // super.onDestroy(); 89 | // } 90 | // 91 | // @Override 92 | // public void onDetach() { 93 | // super.onDetach(); 94 | // } 95 | 96 | @Override 97 | public void onInjectFailed(Exception exception) { 98 | Logger.e(TAG, "inject failed!!: ", exception); 99 | } 100 | 101 | @Override 102 | public Context getContext() { 103 | return context; 104 | } 105 | 106 | @Override 107 | public final void setContentView_(int layoutResID) { 108 | // Fragment不使用次方法进行设置layout,而是在onCreateView中设置,无需实现此方法 109 | } 110 | 111 | @Override 112 | public View findViewById_(int id) { 113 | View view = getView(); 114 | return null == view ? null : view.findViewById(id); 115 | } 116 | 117 | @Override 118 | public void parserTypeAnnotations(Class clazz) throws Exception{} 119 | @Override 120 | public void parserMethodAnnotations(Method method) throws Exception{} 121 | @Override 122 | public void parserFieldAnnotations(Field field) throws Exception {} 123 | 124 | @Override 125 | public void onClickCallbackSample(View view) {} 126 | @Override 127 | public void onLongClickCallbackSample(View view) {} 128 | @Override 129 | public void onItemClickCallbackSample(AdapterView parent, View view, int position, long id) {} 130 | @Override 131 | public void onItemLongClickCallbackSample(AdapterView parent, View view, int position, long id) {} 132 | 133 | @Override 134 | public void onCheckedChangedCallbackSample(CompoundButton buttonView, boolean isChecked) {} 135 | 136 | 137 | } 138 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/present/AIPresent.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.present; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import com.wangjie.androidbucket.mvp.TaskController; 6 | 7 | import java.lang.reflect.Field; 8 | import java.lang.reflect.Method; 9 | 10 | /** 11 | * Created with IntelliJ IDEA. 12 | * User: wangjie email: tiantian.china.2@gmail.com 13 | * Date: 13-11-30 14 | * Time: 下午7:40 15 | * To change this template use File | Settings | File Templates. 16 | */ 17 | public interface AIPresent extends TaskController { 18 | 19 | /** 20 | * Invoke this method when inject failed 21 | * @param exception 22 | * @return 23 | */ 24 | void onInjectFailed(Exception exception); 25 | 26 | Context getContext(); 27 | 28 | void setContentView_(int layoutResID); 29 | 30 | View findViewById_(int resId); 31 | 32 | 33 | /** 34 | * 类型注解额外的解析操作,这个可以交给子类去实现 35 | * 36 | * @param clazz 37 | */ 38 | void parserTypeAnnotations(Class clazz) throws Exception; 39 | 40 | /** 41 | * 方法注解额外的解析操作,这个可以交给子类去实现 42 | * 43 | * @param method 44 | */ 45 | void parserMethodAnnotations(Method method) throws Exception; 46 | 47 | /** 48 | * 属性注解额外的解析操作,这个可以交给子类去实现 49 | * 50 | * @param field 51 | */ 52 | void parserFieldAnnotations(Field field) throws Exception; 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/present/AISubLayout.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.present; 2 | 3 | import android.content.Context; 4 | import android.util.Log; 5 | import android.view.View; 6 | import android.widget.AdapterView; 7 | import android.widget.CompoundButton; 8 | import com.wangjie.androidbucket.customviews.sublayout.SubLayout; 9 | import com.wangjie.androidbucket.log.Logger; 10 | import com.wangjie.androidinject.annotation.core.base.AnnotationManager; 11 | import com.wangjie.androidinject.annotation.present.common.CallbackSample; 12 | 13 | import java.lang.reflect.Field; 14 | import java.lang.reflect.Method; 15 | 16 | /** 17 | * Created by wangjie on 14-5-4. 18 | */ 19 | public class AISubLayout extends SubLayout implements AIPresent, CallbackSample { 20 | private static final String TAG = AISubLayout.class.getSimpleName(); 21 | 22 | public AISubLayout(Context context) { 23 | this(context, false); 24 | } 25 | 26 | public AISubLayout(Context context, boolean autoBindActivityLifeCycle) { 27 | super(context, autoBindActivityLifeCycle); 28 | long start = System.currentTimeMillis(); 29 | try { 30 | new AnnotationManager(this).initAnnotations(); 31 | } catch (Exception e) { 32 | onInjectFailed(e); 33 | } 34 | Log.d(TAG, "[" + ((Object) this).getClass().getSimpleName() + "]AISubLayout(parser annotations) takes: " + (System.currentTimeMillis() - start) + "ms"); 35 | } 36 | 37 | @Override 38 | public void initLayout() { 39 | super.initLayout(); 40 | 41 | } 42 | 43 | @Override 44 | public void onInjectFailed(Exception exception) { 45 | Logger.e(TAG, "inject failed!!: ", exception); 46 | } 47 | 48 | @Override 49 | public Context getContext() { 50 | return context; 51 | } 52 | 53 | @Override 54 | public void setContentView_(int layoutResID) { 55 | setContentView(layoutResID); 56 | } 57 | 58 | @Override 59 | public View findViewById_(int resId) { 60 | return findViewById(resId); 61 | } 62 | 63 | @Override 64 | public void parserTypeAnnotations(Class clazz) throws Exception { 65 | } 66 | 67 | @Override 68 | public void parserMethodAnnotations(Method method) throws Exception { 69 | } 70 | 71 | @Override 72 | public void parserFieldAnnotations(Field field) throws Exception { 73 | } 74 | 75 | @Override 76 | public void onClickCallbackSample(View view) { 77 | } 78 | 79 | @Override 80 | public void onLongClickCallbackSample(View view) { 81 | } 82 | 83 | @Override 84 | public void onItemClickCallbackSample(AdapterView parent, View view, int position, long id) { 85 | } 86 | 87 | @Override 88 | public void onItemLongClickCallbackSample(AdapterView parent, View view, int position, long id) { 89 | } 90 | 91 | @Override 92 | public void onCheckedChangedCallbackSample(CompoundButton buttonView, boolean isChecked) { 93 | } 94 | 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/present/AISupportFragment.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.present; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.os.Bundle; 6 | import android.util.Log; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.AdapterView; 11 | import android.widget.CompoundButton; 12 | import com.wangjie.androidbucket.log.Logger; 13 | import com.wangjie.androidbucket.present.ABSupportFragment; 14 | import com.wangjie.androidinject.annotation.core.base.AnnotationManager; 15 | import com.wangjie.androidinject.annotation.core.base.ParticularAnnotation; 16 | import com.wangjie.androidinject.annotation.present.common.CallbackSample; 17 | 18 | import java.lang.reflect.Field; 19 | import java.lang.reflect.Method; 20 | 21 | /** 22 | * Created with IntelliJ IDEA. 23 | * Author: wangjie email: tiantian.china.2@gmail.com 24 | * Date: 13-12-4 25 | * Time: 下午4:37 26 | */ 27 | public class AISupportFragment extends ABSupportFragment implements AIPresent, CallbackSample{ 28 | private static String TAG = AISupportFragment.class.getSimpleName(); 29 | public Context context; 30 | public Class clazz; 31 | @Override 32 | public void onAttach(Activity activity) { 33 | super.onAttach(activity); 34 | } 35 | 36 | @Override 37 | public void onCreate(Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | context = this.getActivity(); 40 | clazz = ((Object)this).getClass(); 41 | } 42 | 43 | @Override 44 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 45 | return ParticularAnnotation.realizeLayoutAnnotation(this, inflater, container); 46 | } 47 | 48 | @Override 49 | public void onActivityCreated(Bundle savedInstanceState) { 50 | long start = System.currentTimeMillis(); 51 | super.onActivityCreated(savedInstanceState); 52 | try { 53 | new AnnotationManager(this).initAnnotations(); 54 | } catch (Exception e) { 55 | onInjectFailed(e); 56 | } 57 | Log.d(TAG, "[" + clazz.getSimpleName() + "]onActivityCreated supper(parser annotations) takes: " + (System.currentTimeMillis() - start) + "ms"); 58 | } 59 | 60 | // @Override 61 | // public void onStart() { 62 | // super.onStart(); 63 | // } 64 | // 65 | // @Override 66 | // public void onResume() { 67 | // super.onResume(); 68 | // } 69 | // 70 | // @Override 71 | // public void onPause() { 72 | // super.onPause(); 73 | // } 74 | // 75 | // @Override 76 | // public void onStop() { 77 | // super.onStop(); 78 | // } 79 | // 80 | // @Override 81 | // public void onDestroyView() { 82 | // super.onDestroyView(); 83 | // } 84 | // 85 | // @Override 86 | // public void onDestroy() { 87 | // super.onDestroy(); 88 | // } 89 | // 90 | // @Override 91 | // public void onDetach() { 92 | // super.onDetach(); 93 | // } 94 | 95 | @Override 96 | public void onInjectFailed(Exception exception) { 97 | Logger.e(TAG, "inject failed!!: ", exception); 98 | } 99 | 100 | @Override 101 | public Context getContext() { 102 | return context; 103 | } 104 | 105 | @Override 106 | public final void setContentView_(int layoutResID) { 107 | // Fragment不使用次方法进行设置layout,而是在onCreateView中设置,无需实现此方法 108 | } 109 | @Override 110 | public View findViewById_(int id) { 111 | View view = getView(); 112 | return null == view ? null : view.findViewById(id); 113 | } 114 | 115 | @Override 116 | public void parserTypeAnnotations(Class clazz) throws Exception {} 117 | @Override 118 | public void parserMethodAnnotations(Method method) throws Exception {} 119 | @Override 120 | public void parserFieldAnnotations(Field field) throws Exception {} 121 | 122 | @Override 123 | public void onClickCallbackSample(View view) {} 124 | @Override 125 | public void onLongClickCallbackSample(View view) {} 126 | @Override 127 | public void onItemClickCallbackSample(AdapterView parent, View view, int position, long id) {} 128 | @Override 129 | public void onItemLongClickCallbackSample(AdapterView parent, View view, int position, long id) {} 130 | 131 | @Override 132 | public void onCheckedChangedCallbackSample(CompoundButton buttonView, boolean isChecked) {} 133 | 134 | 135 | } 136 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/present/AISupportFragmentActivity.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.present; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.util.Log; 6 | import android.view.View; 7 | import android.widget.AdapterView; 8 | import android.widget.CompoundButton; 9 | import com.wangjie.androidbucket.log.Logger; 10 | import com.wangjie.androidbucket.present.ABSupportFragmentActivity; 11 | import com.wangjie.androidinject.annotation.core.base.AnnotationManager; 12 | import com.wangjie.androidinject.annotation.present.common.CallbackSample; 13 | 14 | import java.lang.reflect.Field; 15 | import java.lang.reflect.Method; 16 | 17 | /** 18 | * Created with IntelliJ IDEA. 19 | * Author: wangjie email: tiantian.china.2@gmail.com 20 | * Date: 13-12-4 21 | * Time: 下午4:21 22 | */ 23 | /** 24 | * @deprecated Use {@link com.wangjie.androidinject.annotation.present.AIAppCompatActivity} instead. 25 | */ 26 | @Deprecated 27 | public class AISupportFragmentActivity extends ABSupportFragmentActivity implements AIPresent, CallbackSample { 28 | private static String TAG = AISupportFragmentActivity.class.getSimpleName(); 29 | public Context context; 30 | public Class clazz; 31 | 32 | @Override 33 | protected void onCreate(Bundle savedInstanceState) { 34 | long start = System.currentTimeMillis(); 35 | super.onCreate(savedInstanceState); 36 | context = this; 37 | clazz = ((Object)this).getClass(); 38 | try { 39 | new AnnotationManager(this).initAnnotations(); 40 | } catch (Exception e) { 41 | onInjectFailed(e); 42 | } 43 | Log.d(TAG, "[" + clazz.getSimpleName() + "]onCreate supper(parser annotations) takes: " + (System.currentTimeMillis() - start) + "ms"); 44 | } 45 | 46 | @Override 47 | protected void onSaveInstanceState(Bundle outState) { 48 | // super.onSaveInstanceState(outState); // 解决Fragment切换时发生重叠现象 49 | } 50 | 51 | @Override 52 | public void onInjectFailed(Exception exception) { 53 | Logger.e(TAG, "inject failed!!: ", exception); 54 | } 55 | 56 | @Override 57 | public Context getContext() { 58 | return context; 59 | } 60 | 61 | @Override 62 | public void setContentView_(int layoutResID) { 63 | setContentView(layoutResID); 64 | } 65 | 66 | @Override 67 | public View findViewById_(int resId) { 68 | return findViewById(resId); 69 | } 70 | 71 | @Override 72 | public void parserTypeAnnotations(Class clazz) throws Exception {} 73 | @Override 74 | public void parserMethodAnnotations(Method method) throws Exception {} 75 | @Override 76 | public void parserFieldAnnotations(Field field) throws Exception {} 77 | 78 | @Override 79 | public void onClickCallbackSample(View view) {} 80 | @Override 81 | public void onLongClickCallbackSample(View view) {} 82 | @Override 83 | public void onItemClickCallbackSample(AdapterView parent, View view, int position, long id) {} 84 | @Override 85 | public void onItemLongClickCallbackSample(AdapterView parent, View view, int position, long id) {} 86 | @Override 87 | public void onCheckedChangedCallbackSample(CompoundButton buttonView, boolean isChecked) {} 88 | 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/present/common/AnnoProcessorAlias.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.present.common; 2 | 3 | import com.wangjie.androidinject.annotation.annotations.base.*; 4 | import com.wangjie.androidinject.annotation.annotations.dimens.AIScreenSize; 5 | import com.wangjie.androidinject.annotation.annotations.mvp.AIPresenter; 6 | import com.wangjie.androidinject.annotation.annotations.net.AINetWorker; 7 | import com.wangjie.androidinject.annotation.cache.common.CommonCache; 8 | import com.wangjie.androidinject.annotation.cache.common.generator.CachedAnnotationProcessorGenerator; 9 | import com.wangjie.androidinject.annotation.core.base.process.AIAnnotationProcessor; 10 | import com.wangjie.androidinject.annotation.core.base.process.field.*; 11 | import com.wangjie.androidinject.annotation.core.base.process.method.*; 12 | import com.wangjie.androidinject.annotation.core.base.process.type.AIFullScreenTypeProcessor; 13 | import com.wangjie.androidinject.annotation.core.base.process.type.AILayoutTypeProcessor; 14 | import com.wangjie.androidinject.annotation.core.base.process.type.AINoTitleTypeProcessor; 15 | 16 | import java.lang.annotation.Annotation; 17 | import java.util.HashMap; 18 | 19 | /** 20 | * Author: wangjie 21 | * Email: tiantian.china.2@gmail.com 22 | * Date: 2/4/15. 23 | */ 24 | public enum AnnoProcessorAlias { 25 | /** 26 | * ************************ Field Annotations BEGIN ***************************** 27 | */ 28 | /** 29 | * 控件注解 30 | */ 31 | AI_VIEW(AIView.class, AIViewFieldProcessor.class), 32 | /** 33 | * MVP注解 34 | */ 35 | AI_PRESENTER(AIPresenter.class, AIPresenterFieldProcessor.class), 36 | /** 37 | * 网络请求注解 38 | */ 39 | AI_NET_WORKER(AINetWorker.class, AINetWorkerFieldProcessor.class), 40 | /** 41 | * java bean注解 42 | */ 43 | AI_BEAN(AIBean.class, AIBeanFieldProcessor.class), 44 | /** 45 | * 屏幕尺寸注解 46 | */ 47 | AI_SCREEN_SIZE(AIScreenSize.class, AIScreenSizeFieldProcessor.class), 48 | /** 49 | * 系统服务注解 50 | */ 51 | AI_SYSTEM_SERVICE(AISystemService.class, AISystemServiceFieldProcessor.class), 52 | /** 53 | * ************************ Field Annotations END ***************************** 54 | */ 55 | 56 | 57 | /** 58 | * ************************ Method Annotations BEGIN ***************************** 59 | */ 60 | /** 61 | * 点击事件注解 62 | */ 63 | AI_CLICK(AIClick.class, AIClickMethodProcessor.class), 64 | /** 65 | * 长按事件注解 66 | */ 67 | AI_LONG_CLICK(AILongClick.class, AILongClickMethodProcessor.class), 68 | /** 69 | * item点击事件注解 70 | */ 71 | AI_ITEM_CLICK(AIItemClick.class, AIItemClickMethodProcessor.class), 72 | /** 73 | * item长按事件注解 74 | */ 75 | AI_ITEM_LONG_CLICK(AIItemLongClick.class, AIItemLongClickMethodProcessor.class), 76 | /** 77 | * 选中事件注解 78 | */ 79 | AI_CHECKED(AIChecked.class, AICheckedMethodProcessor.class), 80 | /** 81 | * ************************ Method Annotations END ***************************** 82 | */ 83 | 84 | 85 | /** 86 | * ************************ Type Annotations BEGIN ***************************** 87 | */ 88 | /** 89 | * 布局注解 90 | */ 91 | AI_LAYOUT(AILayout.class, AILayoutTypeProcessor.class), 92 | /** 93 | * 全部注解 94 | */ 95 | AI_FULL_SCREEN(AIFullScreen.class, AIFullScreenTypeProcessor.class), 96 | /** 97 | * 隐藏Title注解 98 | */ 99 | AI_NO_TITLE(AINoTitle.class, AINoTitleTypeProcessor.class); 100 | 101 | /** 102 | * ************************ Type Annotations END ***************************** 103 | */ 104 | 105 | private static final String TAG = AnnoProcessorAlias.class.getSimpleName(); 106 | 107 | /** 108 | * 缓存annotation类型和对应的解析器 109 | */ 110 | private static HashMap, AnnoProcessorAlias> annotationMapper; 111 | 112 | static { 113 | annotationMapper = new HashMap<>(); 114 | for (AnnoProcessorAlias alias : AnnoProcessorAlias.values()) { 115 | annotationMapper.put(alias.annotationClazz, alias); 116 | } 117 | } 118 | 119 | /** 120 | * 注解处理器的缓存生成器 121 | */ 122 | static CachedAnnotationProcessorGenerator cachedAnnotationProcessorGenerator = new CachedAnnotationProcessorGenerator(); 123 | 124 | /** 125 | * 注解类型 126 | */ 127 | private Class annotationClazz; 128 | /** 129 | * 对应的注解解析器的类型 130 | */ 131 | private Class processorClazz; 132 | 133 | AnnoProcessorAlias(Class annotationClazz, Class processorClazz) { 134 | this.annotationClazz = annotationClazz; 135 | this.processorClazz = processorClazz; 136 | } 137 | 138 | public Class getAnnotationClazz() { 139 | return annotationClazz; 140 | } 141 | 142 | public Class getProcessorClazz() { 143 | return processorClazz; 144 | } 145 | 146 | /** 147 | * 根据注解类型,返回对应的注解解析器类型 148 | * 149 | * @param annotationClazz 150 | * @return 151 | */ 152 | public static AnnoProcessorAlias getAnnotationProcessorAlias(Class annotationClazz) { 153 | return annotationMapper.get(annotationClazz); 154 | } 155 | 156 | public static AIAnnotationProcessor getCachedAnnotationProcessor(final Class annotationClazz) throws Exception{ 157 | cachedAnnotationProcessorGenerator.setAnnotationClazz(annotationClazz); 158 | return CommonCache.getInstance().getCache(AIAnnotationProcessor.class, TAG, annotationClazz, cachedAnnotationProcessorGenerator); 159 | } 160 | 161 | } 162 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/present/common/CallbackSample.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.present.common; 2 | 3 | import android.view.View; 4 | import android.widget.AdapterView; 5 | import android.widget.CompoundButton; 6 | 7 | /** 8 | * Created with IntelliJ IDEA. 9 | * Author: wangjie email: tiantian.china.2@gmail.com 10 | * Date: 13-12-17 11 | * Time: 下午3:36 12 | */ 13 | public interface CallbackSample { 14 | void onClickCallbackSample(View view); 15 | void onLongClickCallbackSample(View view); 16 | void onItemClickCallbackSample(AdapterView parent, View view, int position, long id); 17 | void onItemLongClickCallbackSample(AdapterView parent, View view, int position, long id); 18 | void onCheckedChangedCallbackSample(CompoundButton buttonView, boolean isChecked); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/util/AIDbUtil.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.util; 2 | 3 | import android.database.Cursor; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.util.Log; 6 | 7 | /** 8 | * Created with IntelliJ IDEA. 9 | * Author: wangjie email:tiantian.china.2@gmail.com 10 | * Date: 14-3-25 11 | * Time: 上午9:34 12 | */ 13 | public class AIDbUtil { 14 | public final static String TAG = AIDbUtil.class.getSimpleName(); 15 | /** 16 | * 创建表,如果不存在 17 | * @param db 18 | * @param sql 19 | * @param tableName 20 | */ 21 | public static void createTableIfNotExist(SQLiteDatabase db, String sql, String tableName){ 22 | if(!tableIsExist(db, tableName)){ 23 | // Log.d(TAG, "onUpgrade database, sql: " + sql); 24 | db.execSQL(sql); 25 | } 26 | } 27 | 28 | /** 29 | * 删除表,如果存在 30 | * @param db 31 | * @param sql 32 | * @param tableName 33 | */ 34 | public static void deleteTableIfExist(SQLiteDatabase db, String sql, String tableName){ 35 | if(tableIsExist(db, tableName)){ 36 | // Log.d(TAG, "onUpgrade database, sql: " + sql); 37 | db.execSQL(sql); 38 | } 39 | } 40 | 41 | /** 42 | * 判断某张表是否存在 43 | * @param tableName 表名 44 | * @return 45 | */ 46 | public static boolean tableIsExist(SQLiteDatabase db, String tableName){ 47 | boolean result = false; 48 | if(tableName == null){ 49 | return false; 50 | } 51 | Cursor cursor = null; 52 | try { 53 | // db = this.getReadableDatabase(); 54 | String sql = "select count(*) as c from Sqlite_master where type ='table' and name ='"+tableName.trim()+"' "; 55 | cursor = db.rawQuery(sql, null); 56 | if(cursor.moveToNext()){ 57 | int count = cursor.getInt(0); 58 | if(count>0){ 59 | result = true; 60 | } 61 | } 62 | 63 | } catch (Exception e) { 64 | Log.e(TAG, "[tableIsExist method]error, e: ", e); 65 | } 66 | return result; 67 | } 68 | 69 | /** 70 | * 检查某表列是否存在 71 | * @param db 72 | * @param tableName 表名 73 | * @param columnName 列名 74 | * @return 75 | */ 76 | public static boolean columnExist(SQLiteDatabase db, String tableName 77 | , String columnName) { 78 | boolean result = false ; 79 | Cursor cursor = null ; 80 | try{ 81 | //查询一行 82 | cursor = db.rawQuery( "SELECT * FROM " + tableName + " LIMIT 0" , null ); 83 | result = cursor != null && cursor.getColumnIndex(columnName) != -1 ; 84 | }catch (Exception e){ 85 | Log.e(TAG, "[columnExist method]error, e: ", e); 86 | }finally{ 87 | if(null != cursor && !cursor.isClosed()){ 88 | cursor.close() ; 89 | } 90 | } 91 | 92 | return result ; 93 | } 94 | 95 | public static void closeCursor(Cursor cursor){ 96 | if(null != cursor){ 97 | cursor.close(); 98 | } 99 | } 100 | 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/util/AITextUtil.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.util; 2 | 3 | import org.apache.http.client.utils.URLEncodedUtils; 4 | 5 | import java.net.URLEncoder; 6 | import java.util.Collection; 7 | import java.util.Iterator; 8 | import java.util.Map; 9 | import java.util.Set; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * Author: wangjie email:tiantian.china.2@gmail.com 14 | * Date: 14-3-24 15 | * Time: 下午5:40 16 | */ 17 | public class AITextUtil { 18 | 19 | /** 20 | * 生成占位符 21 | * @param count 22 | * @return 23 | */ 24 | public static String generatePlaceholders(int count){ 25 | if(count <= 0){ 26 | return null; 27 | } 28 | StringBuilder sb = new StringBuilder(); 29 | for(int i = 0; i < count; i++){ 30 | sb.append(",?"); 31 | } 32 | return sb.toString().substring(1); 33 | } 34 | 35 | public static String joinStrings(Collection set, String separator, String append){ 36 | StringBuilder sb = new StringBuilder(); 37 | for(Iterator iter = set.iterator(); iter.hasNext();){ 38 | sb.append(separator).append(iter.next()).append(append); 39 | } 40 | return sb.toString().substring(separator.length()); 41 | } 42 | 43 | public static String joinStrings(Collection set, String separator){ 44 | return joinStrings(set, separator, ""); 45 | } 46 | 47 | public static String appendParamsAfterUrl(String url, Map map){ 48 | if(null == map || map.isEmpty()){ 49 | return url; 50 | } 51 | StringBuilder sb = new StringBuilder(url); 52 | sb = url.contains("?") ? sb.append("&") : sb.append("?"); 53 | Set set = map.entrySet(); 54 | for(Map.Entry entry : set){ 55 | sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); 56 | } 57 | url = sb.toString(); 58 | return url.substring(0, url.length() - 1); 59 | } 60 | 61 | public static String joinArray(String[] array, String separator){ 62 | if(null == array || array.length <= 0){ 63 | return ""; 64 | } 65 | StringBuilder sb = new StringBuilder(); 66 | for(String s : array){ 67 | sb.append(separator).append(s); 68 | } 69 | return sb.toString().substring(separator.length()); 70 | } 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/util/Params.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.util; 2 | 3 | import org.apache.http.NameValuePair; 4 | import org.apache.http.message.BasicNameValuePair; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * Author: wangjie email:tiantian.china.2@gmail.com 12 | * Date: 14-2-8 13 | * Time: 上午10:41 14 | */ 15 | public class Params { 16 | private List nameValuePairs = new ArrayList<>(); 17 | 18 | public Params add(String key, Object value) { 19 | if (null == key || null == value) { 20 | return this; 21 | } 22 | nameValuePairs.add(new BasicNameValuePair(key, String.valueOf(value))); 23 | return this; 24 | } 25 | 26 | public Params put(String key, Object value) { 27 | return add(key, value); 28 | } 29 | 30 | public Params putAll(Params params) { 31 | if (null == params) { 32 | return this; 33 | } 34 | this.nameValuePairs.addAll(params.getNameValuePairs()); 35 | return this; 36 | } 37 | 38 | public List getNameValuePairs() { 39 | return nameValuePairs; 40 | } 41 | 42 | public void clear() { 43 | nameValuePairs.clear(); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/com/wangjie/androidinject/annotation/util/SystemServiceUtil.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidinject.annotation.util; 2 | 3 | import android.app.*; 4 | import android.content.Context; 5 | import android.location.LocationManager; 6 | import android.media.AudioManager; 7 | import android.net.ConnectivityManager; 8 | import android.net.wifi.WifiManager; 9 | import android.os.PowerManager; 10 | import android.os.Vibrator; 11 | import android.view.LayoutInflater; 12 | import android.view.WindowManager; 13 | import android.view.inputmethod.InputMethodManager; 14 | 15 | /** 16 | * Created with IntelliJ IDEA. 17 | * Author: wangjie email: tiantian.china.2@gmail.com 18 | * Date: 13-12-2 19 | * Time: 下午4:43 20 | */ 21 | public class SystemServiceUtil { 22 | 23 | public static Object getSystemServiceByClazz(Context context, Class clazz) throws Exception{ 24 | String serviceName = null; 25 | 26 | if(clazz == WindowManager.class){ 27 | serviceName = Context.WINDOW_SERVICE; 28 | }else if(clazz == LayoutInflater.class){ 29 | serviceName = Context.LAYOUT_INFLATER_SERVICE; 30 | }else if(clazz == ActivityManager.class){ 31 | serviceName = Context.ACTIVITY_SERVICE; 32 | }else if(clazz == PowerManager.class){ 33 | serviceName = Context.POWER_SERVICE; 34 | }else if(clazz == AlarmManager.class){ 35 | serviceName = Context.ALARM_SERVICE; 36 | }else if(clazz == NotificationManager.class){ 37 | serviceName = Context.NOTIFICATION_SERVICE; 38 | }else if(clazz == KeyguardManager.class){ 39 | serviceName = Context.KEYGUARD_SERVICE; 40 | }else if(clazz == LocationManager.class){ 41 | serviceName = Context.LOCATION_SERVICE; 42 | }else if(clazz == SearchManager.class){ 43 | serviceName = Context.SEARCH_SERVICE; 44 | }else if(clazz == Vibrator.class){ 45 | serviceName = Context.VIBRATOR_SERVICE; 46 | }else if(clazz == ConnectivityManager.class){ 47 | serviceName = Context.CONNECTIVITY_SERVICE; 48 | }else if(clazz == WifiManager.class){ 49 | serviceName = Context.WIFI_SERVICE; 50 | }else if(clazz == InputMethodManager.class){ 51 | serviceName = Context.INPUT_METHOD_SERVICE; 52 | }else if(clazz == UiModeManager.class){ 53 | serviceName = Context.UI_MODE_SERVICE; 54 | }else if(clazz == DownloadManager.class){ 55 | serviceName = Context.DOWNLOAD_SERVICE; 56 | }else if(clazz == AudioManager.class){ 57 | serviceName = Context.AUDIO_SERVICE; 58 | } 59 | 60 | if(null == serviceName){ 61 | throw new Exception(clazz.getName() + " is not a SystemService ! "); 62 | } 63 | 64 | return context.getSystemService(serviceName); 65 | } 66 | 67 | } 68 | --------------------------------------------------------------------------------