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中
- dependencies {
- classpath 'com.android.tools.build:gradle:2.1.0-alpha3'
- // the latest version of the android-apt plugin
- classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
- }
在module gradle中
- apply plugin: 'com.android.application'
- apply plugin: 'com.neenbedankt.android-apt'
-
- dependencies {
- apt "org.androidannotations:androidannotations:4.0.0"
- compile "org.androidannotations:androidannotations-api:4.0.0"
- }
- apt {
- arguments {
- androidManifestFile variant.outputs[0]?.processResources?.manifestFile
- }
- }
这样,你就可以在代码中使用它了...
三.在xml中声明
当使用控件的时候,在xml中注册要加上 _ 比如,自定义了一个view 叫MyView 注册的时候要注册为 MyView_.它是继承自叫MyView.
Activity和Service注册的时候也一样.
这就是为什么AA不影响效率的原因
- <activity android:name=".MyListActivity_" />
- <fragment
- android:id="@+id/myFragment"
- android:name="com.company.MyFragment_"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" />
- <com.androidannotations.view.CustomButton_
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
在你没有make project 之前,使用_ 类会报错,你make一下就行了
四.在类中使用
重头戏来了
@EActivity
声明activity
- @EActivity(R.layout.main)
- public class MyActivity extends Activity {
- }
这样你都可以不用写 oncreate() 方法了.当然,你也可以这样
- @EActivity
- public class MyListActivity extends ListActivity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- }
不建议这么写,因为,你在使用AA的时候,使用 @ViewById 获取view不能
oncreate() 中直接使用那个view,oncreate 的时候那个view还没有找到,需要在 @AfterViews 中使用view
启动activity
使用原生代码的启动
- startActivity(this, MyListActivity_.class);
使用AA启动
- // Starting the activity
- MyListActivity_.intent(context).start();
- // Building an intent from the activity
- Intent intent = MyListActivity_.intent(context).get();
- // You can provide flags
- MyListActivity_.intent(context).flags(FLAG_ACTIVITY_CLEAR_TOP).start();
- // You can even provide extras defined with @Extra in the activity
- MyListActivity_.intent(context).myDateExtra(someDate).start();
使用options 来传递bundle对象
- MyListActivity_.intent(context).withOptions(bundle).start();
为页面的跳转添加过场动画
- MyListActivity_.intent(context).start().withAnimation(enterAnimRes, exitAnimRes));
要使用 startActivityForResult() 功能,则通过
- MyListActivity_.intent(context).startForResult(REQUEST_CODE,intent);
然后,你可以通过使用 @OnActivityResult 来得到返回值和数据
- @OnActivityResult(REQUEST_CODE)
- void onResult(int resultCode, Intent data) {
- }
- @OnActivityResult(REQUEST_CODE)
- void onResult(int resultCode) {
- }
- @OnActivityResult(ANOTHER_REQUEST_CODE)
- void onResult(Intent data) {
- }
- @OnActivityResult(ANOTHER_REQUEST_CODE)
- void onResult() {
- }
启动service
原生代码启动
- startService(this, MyService_.class);
使用AA启动
- // Starting the service
- MyService_.intent(context).start();
- // Building an intent from the activity
- Intent intent = MyService_.intent(context).build();
- // You can provide flags
- MyService_.intent(context).flags(Intent.FLAG_GRANT_READ_URI_PERMISSION).start();
@EFragment
- @EFragment
- public class MyFragment extends Fragment {
- }
为Fragment添加布局
- @EFragment(R.layout.my_fragment_layout)
- public class MyFragment extends Fragment {
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- return null;
- }
- }
注意: onCeateView() 不能删掉,并且要返回null
在xml中,需要注册 MyFragment_
在代码中通过以下方式创建
- //1.
- MyFragment fragment = new MyFragment_();
- //2.
- MyFragment fragment = MyFragment_.builder().build();
使用 @FragmentById与 @FragmentByTag 来映射Fragment,建议使用 @FragmentById,因为它更快
- @EActivity(R.layout.fragments)
- public class MyFragmentActivity extends FragmentActivity {
- @FragmentById
- MyFragment myFragment;
- @FragmentById(R.id.myFragment)
- MyFragment myFragment2;
- @FragmentByTag
- MyFragment myFragmentTag;
- @FragmentByTag("myFragmentTag")
- MyFragment myFragmentTag2;
- }
@EView
- @EView
- public class CustomButton extends Button {
- @App
- MyApplication application;
- @StringRes
- String someStringResource;
- public CustomButton(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- }
在XML中声明
- <com.androidannotations.view.CustomButton_
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
在代码中使用
- CustomButton button = CustomButton_.build(context);
@EViewGroup
自定义ViewGroup
在xml中使用merge来定义布局
merge可去掉重复布局,提高效率,请自行百度
- <?xml version="1.0" encoding="utf-8"?>
- <merge xmlns:android="http://schemas.android.com/apk/res/android" >
- <ImageView
- android:id="@+id/image"
- android:layout_alignParentRight="true"
- android:layout_alignBottom="@+id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/check" />
- <TextView
- android:id="@+id/title"
- android:layout_toLeftOf="@+id/image"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textColor="@android:color/white"
- android:textSize="12pt" />
- <TextView
- android:id="@+id/subtitle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@+id/title"
- android:textColor="#FFdedede"
- android:textSize="10pt" />
- </merge>
然后自定义
- @EViewGroup(R.layout.title_with_subtitle)
- public class TitleWithSubtitle extends RelativeLayout {
- @ViewById
- protected TextView title, subtitle;
- public TitleWithSubtitle(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
- public void setTexts(String titleText, String subTitleText) {
- title.setText(titleText);
- subtitle.setText(subTitleText);
- }
- }
使用自定义ViewGroup
- <com.androidannotations.viewgroup.TitleWithSubtitle_
- android:id="@+id/firstTitle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- @EActivity(R.layout.main)
- public class Main extends Activity {
- @ViewById
- protected TitleWithSubtitle firstTitle, secondTitle, thirdTitle;
- @AfterViews
- protected void init() {
- firstTitle.setTexts("decouple your code",
- "Hide the component logic from the code using it.");
- secondTitle.setTexts("write once, reuse anywhere",
- "Declare you component in multiple " +
- "places, just as easily as you " +
- "would put a single basic View.");
- thirdTitle.setTexts("Let's get stated!",
- "Let's see how AndroidAnnotations can make it easier!");
- }
- }
@ViewById
用来映射view,相当于 findViewById()
- @EActivity
- public class MyActivity extends Activity {
- // Injects R.id.myEditText
- @ViewById
- EditText myEditText;
- @ViewById(R.id.myTextView)
- TextView textView;
- }
注意: 当 onCreate() 调用的时候, @ViewById还没有获取到view,所以不能再 onCreate() 中使用用注释声明的view,你需要在 @AfterViews中使用控件.
还可以通过这种方式初始化
- @EActivity
- public class MyActivity extends Activity {
- @ViewById
- void setOneView(EditText myEditText){
- // do something with myEditText
- }
- void setMultipleBeans(@ViewById EditText myEditText, @ViewById(R.id.myTextView) TextView textView){
- // do something with myEditText and textView
- }
- }
使用这个方法,是在 onCreate() 创建之后调用.
@AfterViews
用于初始化控件
- @EActivity(R.layout.main)
- public class MyActivity extends Activity {
- @ViewById
- TextView myTextView;
- @AfterViews
- void initViews() {
- myTextView.setText("Date: " + new Date());
- }
这样结合才能不报错.
ClickEvents
- @Click(R.id.myButton)
- void myButtonWasClicked() {
- [...]
- }
- // Injects R.id.anotherButton
- @Click
- void anotherButton() {
- [...]
- }
- @Click({R.id.myButton, R.id.myOtherButton})
- void handlesTwoButtons() {
- [...]
- }
@LongClick @Touch 与其用法相同
@Extra
@Extra 要和 startActivity 配合使用
在AActivity中发送hello数据
- @EActivity
- public class AActivity extens Activity{
- MyActivity_.intent().myMessage("hello").start() ;
- }
在BActivity中,从AActivity中接受数据,这里myStringExtra="hello"
- @EActivity
- public class BActivity extends Activity {
- @Extra("myMessage")
- String myStringExtra;
- //form AActivity: myStringExtra = "hello"
-
- // Injects "myMessage"
- @Extra
- String myMessage;
-
- @Extra("myMessage")
- void setOneExtra(String message){
- // do somethiBng with message
- }
- }
@Background
让任务在工作线程中执行
基本使用
- void myMethod() {
- someBackgroundWork("hello", 42);
- }
- @Background
- void someBackgroundWork(String aParam, long anotherParam) {
- [...]
- }
使用id标签,来取消一个线程任务
- void myMethod() {
- //执行
- someCancellableBackground("hello", 42);
- [...]
- //用于取消
- boolean mayInterruptIfRunning = true;
- BackgroundExecutor.cancelAll("cancellable_task", mayInterruptIfRunning);
- }
- @Background(id="cancellable_task")
- void someCancellableBackground(String aParam, long anotherParam) {
- [...]
- }
使用Serial标签,来按顺序执行线程任务
- void myMethod() {
- for (int i = 0; i < 10; i++)
- someSequentialBackgroundMethod(i);
- }
- @Background(serial = "test")
- void someSequentialBackgroundMethod(int i) {
- SystemClock.sleep(new Random().nextInt(2000)+1000);
- Log.d("AA", "value : " + i);
- }
使用 Delay标签, 用于延迟任务的执行
- @Background(delay=2000)
- void doInBackgroundAfterTwoSeconds() {
- }
@UiThread
让任务在UI线程中执行
基本使用
- void myMethod() {
- doInUiThread("hello", 42);
- }
- @UiThread
- void doInUiThread(String aParam, long anotherParam) {
- [...]
- }
Delay,延迟执行
- @UiThread(delay=2000)
- void doInUiThreadAfterTwoSeconds() {
- }
propagation 比较有效率的方式
- @UiThread(propagation = Propagation.REUSE)
- void runInSameThreadIfOnUiThread() {
- }
id,用于取消
- void myMethod() {
- someCancellableUiThreadMethod("hello", 42);
- [...]
- UiThreadExecutor.cancelAll("cancellable_task");
- }
- @UiThread(id="cancellable_task")
- void someCancellableUiThreadMethod(String aParam, long anotherParam) {
- [...]
- }
@SupposeBackground @SupposeUiThread
注释在方法上,说明该方法应该运行在UI线程或者非UI线程,如果没有按要求,则报错
注意: 这个只是提醒你要在哪个线程中执行,而不是创建线程让你在该线程执行.
五.配合 android layout id converter使用
快速的findViewById
使用方法:在你的布局文件当中右键,在弹出来的菜单当中选择Convert Android layout xml,如下图所示:

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

该插件支持原生 findViewById 和 ButterKnife AndroidAnnotations

浙公网安备 33010602011771号