AndroidAnnotations简明指南

一.简介

AndroidAnnotations是注释框架,它能够让你快速进行Android开发的开源框架,它能让你专注于真正重要的地方。使代码更加精简,使项目更加容易维护,它的目标就是

“Fast Android Development.Easy maintainance”。

优势

让代码更加的便捷,易于维护
  这应该是注释框架,最基本的功能了。

异步操作
通过简单的 @Background @UiThread 来实现主线程和工作线程的切换,免去自启线程的操作

虽是注释,但是不影响速度,性能。
  AndroidAnnotations,实现的原理:通过使用jdk 1.6引入的Java Annotation Processing Tool,在编译器中加了一层额外的自动编译步骤,用来生成基于你源码的代码,生成的代码是你源码的直接子类。
  意思是当你build项目的时候,AndroidAnnotations会生成一套新的代码,而你最终跑的就是这套代码,所以运行的时候不会有额外时间,将时间提到编译层了。

代码添加代价比较低
  导入框架大小不到50k

劣势

劣势是:找不到劣势!!!
  硬要说就是build的时候,要额外一点时间。还有就是你在项目中太过依赖它,然后公司开发正式项目的时候不让你用这个框架,这就有点恼。

项目地址

github项目 AndroidAnnotations
文档 AndroidAnnotations

二.使用前的配置

需要添加高亮的代码,版本号改成最新的即可

在project gradle中

  1. dependencies
  2. classpath 'com.android.tools.build:gradle:2.1.0-alpha3' 
  3. // the latest version of the android-apt plugin 
  4. classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' 

在module gradle中

  1. apply plugin: 'com.android.application' 
  2. apply plugin: 'com.neenbedankt.android-apt' 
  3.  
  4. dependencies
  5. apt "org.androidannotations:androidannotations:4.0.0" 
  6. compile "org.androidannotations:androidannotations-api:4.0.0" 

  7. apt { 
  8. arguments { 
  9. androidManifestFile variant.outputs[0]?.processResources?.manifestFile 

  10. } 

这样,你就可以在代码中使用它了...

三.在xml中声明

当使用控件的时候,在xml中注册要加上 _ 比如,自定义了一个view 叫MyView 注册的时候要注册为 MyView_.它是继承自叫MyView.
Activity和Service注册的时候也一样.
这就是为什么AA不影响效率的原因

  1. <activity android:name=".MyListActivity_" /> 
  1. <fragment 
  2. android:id="@+id/myFragment" 
  3. android:name="com.company.MyFragment_" 
  4. android:layout_width="fill_parent" 
  5. android:layout_height="fill_parent" /> 
  1. <com.androidannotations.view.CustomButton_ 
  2. android:layout_width="match_parent" 
  3. android:layout_height="wrap_content" /> 

在你没有make project 之前,使用_ 类会报错,你make一下就行了

四.在类中使用

重头戏来了

@EActivity

声明activity

  1. @EActivity(R.layout.main) 
  2. public class MyActivity extends Activity

这样你都可以不用写 oncreate() 方法了.当然,你也可以这样

  1. @EActivity 
  2. public class MyListActivity extends ListActivity
  3. @Override 
  4. public void onCreate(Bundle savedInstanceState)
  5. super.onCreate(savedInstanceState); 
  6. setContentView(R.layout.main); 


不建议这么写,因为,你在使用AA的时候,使用 @ViewById 获取view不能
oncreate() 中直接使用那个view,oncreate 的时候那个view还没有找到,需要在 @AfterViews 中使用view

启动activity
使用原生代码的启动

  1. startActivity(this, MyListActivity_.class); 

使用AA启动

  1. // Starting the activity 
  2. MyListActivity_.intent(context).start(); 
  3. // Building an intent from the activity 
  4. Intent intent = MyListActivity_.intent(context).get(); 
  5. // You can provide flags 
  6. MyListActivity_.intent(context).flags(FLAG_ACTIVITY_CLEAR_TOP).start(); 
  7. // You can even provide extras defined with @Extra in the activity 
  8. MyListActivity_.intent(context).myDateExtra(someDate).start(); 

使用options 来传递bundle对象

  1. MyListActivity_.intent(context).withOptions(bundle).start(); 

为页面的跳转添加过场动画

  1. MyListActivity_.intent(context).start().withAnimation(enterAnimRes, exitAnimRes)); 

要使用 startActivityForResult() 功能,则通过

  1. MyListActivity_.intent(context).startForResult(REQUEST_CODE,intent); 

然后,你可以通过使用 @OnActivityResult 来得到返回值和数据

  1. @OnActivityResult(REQUEST_CODE) 
  2. void onResult(int resultCode, Intent data)

  3. @OnActivityResult(REQUEST_CODE) 
  4. void onResult(int resultCode)

  5. @OnActivityResult(ANOTHER_REQUEST_CODE) 
  6. void onResult(Intent data)

  7. @OnActivityResult(ANOTHER_REQUEST_CODE) 
  8. void onResult()

启动service
原生代码启动

  1. startService(this, MyService_.class); 

使用AA启动

  1. // Starting the service 
  2. MyService_.intent(context).start(); 
  3. // Building an intent from the activity 
  4. Intent intent = MyService_.intent(context).build(); 
  5. // You can provide flags 
  6. MyService_.intent(context).flags(Intent.FLAG_GRANT_READ_URI_PERMISSION).start(); 

@EFragment

  1. @EFragment 
  2. public class MyFragment extends Fragment

为Fragment添加布局

  1. @EFragment(R.layout.my_fragment_layout) 
  2. public class MyFragment extends Fragment
  3. public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
  4. return null


注意: onCeateView() 不能删掉,并且要返回null

在xml中,需要注册 MyFragment_
在代码中通过以下方式创建

  1. //1. 
  2. MyFragment fragment = new MyFragment_(); 
  3. //2. 
  4. MyFragment fragment = MyFragment_.builder().build(); 

使用 @FragmentById@FragmentByTag 来映射Fragment,建议使用 @FragmentById,因为它更快

  1. @EActivity(R.layout.fragments) 
  2. public class MyFragmentActivity extends FragmentActivity
  3. @FragmentById 
  4. MyFragment myFragment; 
  5. @FragmentById(R.id.myFragment) 
  6. MyFragment myFragment2; 
  7. @FragmentByTag 
  8. MyFragment myFragmentTag; 
  9. @FragmentByTag("myFragmentTag"
  10. MyFragment myFragmentTag2; 

@EView

  1. @EView 
  2. public class CustomButton extends Button
  3. @App 
  4. MyApplication application; 
  5. @StringRes 
  6. String someStringResource; 
  7. public CustomButton(Context context, AttributeSet attrs)
  8. super(context, attrs); 


在XML中声明

  1. <com.androidannotations.view.CustomButton_ 
  2. android:layout_width="match_parent" 
  3. android:layout_height="wrap_content" /> 

在代码中使用

  1. CustomButton button = CustomButton_.build(context); 

@EViewGroup

自定义ViewGroup
在xml中使用merge来定义布局

merge可去掉重复布局,提高效率,请自行百度

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <merge xmlns:android="http://schemas.android.com/apk/res/android" > 
  3. <ImageView 
  4. android:id="@+id/image" 
  5. android:layout_alignParentRight="true" 
  6. android:layout_alignBottom="@+id/title" 
  7. android:layout_width="wrap_content" 
  8. android:layout_height="wrap_content" 
  9. android:src="@drawable/check" /> 
  10. <TextView 
  11. android:id="@+id/title" 
  12. android:layout_toLeftOf="@+id/image" 
  13. android:layout_width="match_parent" 
  14. android:layout_height="wrap_content" 
  15. android:textColor="@android:color/white" 
  16. android:textSize="12pt" /> 
  17. <TextView 
  18. android:id="@+id/subtitle" 
  19. android:layout_width="match_parent" 
  20. android:layout_height="wrap_content" 
  21. android:layout_below="@+id/title" 
  22. android:textColor="#FFdedede" 
  23. android:textSize="10pt" /> 
  24. </merge> 

然后自定义

  1. @EViewGroup(R.layout.title_with_subtitle) 
  2. public class TitleWithSubtitle extends RelativeLayout
  3. @ViewById 
  4. protected TextView title, subtitle; 
  5. public TitleWithSubtitle(Context context, AttributeSet attrs)
  6. super(context, attrs); 

  7. public void setTexts(String titleText, String subTitleText)
  8. title.setText(titleText); 
  9. subtitle.setText(subTitleText); 


使用自定义ViewGroup

  1. <com.androidannotations.viewgroup.TitleWithSubtitle_ 
  2. android:id="@+id/firstTitle" 
  3. android:layout_width="match_parent" 
  4. android:layout_height="wrap_content" /> 
  1. @EActivity(R.layout.main) 
  2. public class Main extends Activity
  3. @ViewById 
  4. protected TitleWithSubtitle firstTitle, secondTitle, thirdTitle; 
  5. @AfterViews 
  6. protected void init()
  7. firstTitle.setTexts("decouple your code"
  8. "Hide the component logic from the code using it."); 
  9. secondTitle.setTexts("write once, reuse anywhere"
  10. "Declare you component in multiple "
  11. "places, just as easily as you "
  12. "would put a single basic View."); 
  13. thirdTitle.setTexts("Let's get stated!"
  14. "Let's see how AndroidAnnotations can make it easier!"); 


@ViewById

用来映射view,相当于 findViewById()

  1. @EActivity 
  2. public class MyActivity extends Activity
  3. // Injects R.id.myEditText 
  4. @ViewById 
  5. EditText myEditText; 
  6. @ViewById(R.id.myTextView) 
  7. TextView textView; 

注意: 当 onCreate() 调用的时候, @ViewById还没有获取到view,所以不能再 onCreate() 中使用用注释声明的view,你需要在 @AfterViews中使用控件.

还可以通过这种方式初始化

  1. @EActivity 
  2. public class MyActivity extends Activity
  3. @ViewById 
  4. void setOneView(EditText myEditText)
  5. // do something with myEditText 

  6. void setMultipleBeans(@ViewById EditText myEditText, @ViewById(R.id.myTextView) TextView textView)
  7. // do something with myEditText and textView 


使用这个方法,是在 onCreate() 创建之后调用.

@AfterViews

用于初始化控件

  1. @EActivity(R.layout.main) 
  2. public class MyActivity extends Activity
  3. @ViewById 
  4. TextView myTextView; 
  5. @AfterViews 
  6. void initViews()
  7. myTextView.setText("Date: " + new Date()); 

这样结合才能不报错.

ClickEvents

  1. @Click(R.id.myButton) 
  2. void myButtonWasClicked()
  3. [...] 

  4. // Injects R.id.anotherButton 
  5. @Click 
  6. void anotherButton()
  7. [...] 

  8. @Click({R.id.myButton, R.id.myOtherButton}) 
  9. void handlesTwoButtons()
  10. [...] 

@LongClick @Touch 与其用法相同

@Extra

@Extra 要和 startActivity 配合使用

在AActivity中发送hello数据

  1. @EActivity 
  2. public class AActivity extens Activity
  3. MyActivity_.intent().myMessage("hello").start() ; 

在BActivity中,从AActivity中接受数据,这里myStringExtra="hello"

  1. @EActivity 
  2. public class BActivity extends Activity
  3. @Extra("myMessage"
  4. String myStringExtra; 
  5. //form AActivity: myStringExtra = "hello" 
  6.  
  7. // Injects "myMessage" 
  8. @Extra 
  9. String myMessage; 
  10.  
  11. @Extra("myMessage"
  12. void setOneExtra(String message)
  13. // do somethiBng with message 


@Background

让任务在工作线程中执行

基本使用

  1. void myMethod()
  2. someBackgroundWork("hello", 42); 

  3. @Background 
  4. void someBackgroundWork(String aParam, long anotherParam)
  5. [...] 

使用id标签,来取消一个线程任务

  1. void myMethod()
  2. //执行 
  3. someCancellableBackground("hello", 42); 
  4. [...] 
  5. //用于取消 
  6. boolean mayInterruptIfRunning = true
  7. BackgroundExecutor.cancelAll("cancellable_task", mayInterruptIfRunning); 

  8. @Background(id="cancellable_task"
  9. void someCancellableBackground(String aParam, long anotherParam)
  10. [...] 

使用Serial标签,来按顺序执行线程任务

  1. void myMethod()
  2. for (int i = 0; i < 10; i++) 
  3. someSequentialBackgroundMethod(i); 

  4. @Background(serial = "test"
  5. void someSequentialBackgroundMethod(int i)
  6. SystemClock.sleep(new Random().nextInt(2000)+1000); 
  7. Log.d("AA", "value : " + i); 

使用 Delay标签, 用于延迟任务的执行

  1. @Background(delay=2000
  2. void doInBackgroundAfterTwoSeconds()

@UiThread

让任务在UI线程中执行

基本使用

  1. void myMethod()
  2. doInUiThread("hello", 42); 

  3. @UiThread 
  4. void doInUiThread(String aParam, long anotherParam)
  5. [...] 

Delay,延迟执行

  1. @UiThread(delay=2000
  2. void doInUiThreadAfterTwoSeconds()

propagation 比较有效率的方式

  1. @UiThread(propagation = Propagation.REUSE) 
  2. void runInSameThreadIfOnUiThread()

id,用于取消

  1. void myMethod()
  2. someCancellableUiThreadMethod("hello", 42); 
  3. [...] 
  4. UiThreadExecutor.cancelAll("cancellable_task"); 

  5. @UiThread(id="cancellable_task"
  6. void someCancellableUiThreadMethod(String aParam, long anotherParam)
  7. [...] 

@SupposeBackground @SupposeUiThread

注释在方法上,说明该方法应该运行在UI线程或者非UI线程,如果没有按要求,则报错
注意: 这个只是提醒你要在哪个线程中执行,而不是创建线程让你在该线程执行.

五.配合 android layout id converter使用

快速的findViewById
使用方法:在你的布局文件当中右键,在弹出来的菜单当中选择Convert Android layout xml,如下图所示:
enter description here

然后它会弹出一个面板,如下所示。选择要生成的代码的格式,按OK,这时它已经把生成的代码复制在你的粘贴板中,然后你在使用这个布局文件的Activity或Fragment中,按Ctrl + V 把代码粘贴出来就可以了。
enter description here

该插件支持原生 findViewByIdButterKnife AndroidAnnotations

posted @ 2016-04-16 14:02  JimmieYang  阅读(544)  评论(0)    收藏  举报