【Android】使用Annotation注解框架

Enhanced components

  • @EAactivity
    这个注解主要用来加载Activity的布局,其中value参数必须是有效的布局ID,他将用做Activity的内容视图。您可以将value参数保留为空,这意味着不会设置任何的内容视图,您可能希望onCreate()在绑定完成之前在方法中自己设置内容视图
@EActivity(R.layout.main)
public class MyActivity extends Activity {

}
@EActivity
public class MyListActivity extends ListActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

}
  • @EReceiver
    你可以使用@EReceiver来标注一个广播接受者
@EReceiver
public class MyReceiver extends BroadcastReceiver {

}

然后,您可以开始使用大多数AA annotations,但与视图和附加内容相关的注释除外:

@EReceiver
public class MyReceiver extends BroadcastReceiver {

  @SystemService
  NotificationManager notificationManager;

  @Bean
  SomeObject someObject;
  
}

该@ReceiverAction注释允许简单地处理广播在增强的接收机。

默认情况下,方法名称用于确定要处理的操作,但您可以使用值@ReceiverAction来传递另一个操作名称。

注释的方法@ReceiverAction可能具有以下参数:

  • 一个android.content.Context将在被上下文给出void onReceive(Context context, Intent intent)
  • 一个android.content.Intent将在被意图给出void onReceive(Context context, Intent intent)
  • 任何本机android.os.Parcelable或java.io.Serializable带注释的参数@ReceiverAction.Extra将是意图中的额外放置。这个额外的关键是注释的值(@ReceiverAction.Extra如果设置)或参数的名称。
@EReceiver
public class MyIntentService extends BroadcastReceiver {

	@ReceiverAction("BROADCAST_ACTION_NAME")
	void mySimpleAction(Intent intent) {
		// ...
	}

	@ReceiverAction
	void myAction(@ReceiverAction.Extra String valueString, Context context) {
		// ...
	}

	@ReceiverAction
	void anotherAction(@ReceiverAction.Extra("specialExtraName") String valueString, @ReceiverAction.Extra long valueLong) {
		// ...
	}

	@Override
	public void onReceive(Context context, Intent intent) {
		// empty, will be overridden in generated subclass
	}
}

注意:由于BroadcastReceiver#onReceive是抽象的,您必须添加一个空实现。为方便起见,我们提供了AbstractBroadcastReceiver实现该方法的类,因此如果您派生它,则不必在实际的类中执行。

注意:您现在可以通过使用值来传递应该处理的多个操作@ReceiverAction。

    @ReceiverAction({ “ MULTI_BROADCAST_ACTION1 ”,“ MULTI_BROADCAST_ACTION2 ” })
     void multiAction(Intent intent){
         // ... 
    }

数据方案
使用该dataScheme参数,您可以设置应由Receiver处理的一个或多个dataSchemes。

@EReceiver 
公共 类 MyIntentService  扩展 BroadcastReceiver {

  @ReceiverAction(行动 =  android.content 。意向。 VIEW,dataSchemes  =  “ HTTP ”)
   保护 无效 onHttp(){
     //将当一个应用程序要开一个HTTP网站,但不是HTTPS被调用。
  }
  
  @ReceiverAction(行动 =  android.content 。意向。 VIEW,dataSchemes  = { “ HTTP ”,“ HTTPS ” })
   保护 无效 onHttps(){
     //将当一个应用程序要开HTTP或HTTPS网站被调用。
  }

}

@Receiver注释
您的活动/片段/服务可以使用@Receiver注释通知意图,而不是声明 BroadcastReceiver。

@EActivity
public class MyActivity extends Activity {

  @Receiver(actions = "org.androidannotations.ACTION_1")
  protected void onAction1() {

  }

}

Injection

  • @Extra
@EActivity
public class MyActivity extends Activity {

  @Extra("myStringExtra")
  String myMessage;
	
  @Extra("myDateExtra")
  Date myDateExtraWithDefaultValue = new Date();

}

Since AndroidAnnotations 4.0.0

@EActivity
public class MyActivity extends Activity {

  @Extra("myStringExtra")
  void setOneExtra(String myMessage){
    // do something with myMessage
  }
  
   void setMultipleExtrass(@Extra String myMessage, @Extra("myDateExtra") Date myDateExtraWithDefaultValue){
    // do something with myMessage and myDateExtraWithDefaultValue
  }

}

请注意,您可以使用intent构建器传递额外的值。

MyActivity_.intent().myMessage("hello").start() ;

处理 onNewIntent()

自AndroidAnnotations 2.6

AndroidAnnotations会覆盖setIntent(),并Intent在您调用时根据给定的内容自动重新注入额外内容setIntent()。

这使您可以通过调用自动重新注入额外setIntent()的onNewIntent()。

@EActivity 
公共 类 MyActivity  扩展 Activity {

    @Extra(“ myStringExtra ”)
     String myMessage;

    @覆盖
    保护 无效 onNewIntent(意向 意图){
         超。onNewIntent(意向);
        setIntent(意向);
    }
}

自AndroidAnnotations 3.2

当@AfterExtras在活动中出现带注释的方法时,我们会覆盖onNewIntent()要调用的方法setIntent()。

自AndroidAnnotations 4.0.0起

警告:从Android Annotations 4.0.0开始,我们不再覆盖onNewIntent(),如果需要,您必须自己覆盖它。

额外注入后执行代码

自AndroidAnnotations 3.1

如果需要在extras注入后执行代码,则应该@AfterExtras在某些方法上使用注释。

@EActivity 
public  class  MyClass {

  @Extra 
  String someExtra;

  @Extra 
  int anotherExtra;


  @AfterExtras 
  public  void  doSomethingAfterExtrasInjection(){
     // someExtra和anotherExtra设置为传入intent中包含的值
    //如果intent不包含其中一个额外值,则该字段保持不变
  }

}

警告

如果父类和子类有@AfterViews,@AfterInject或@AfterExtras标注了相同名称的方法,生成的代码将是马车。

此外,虽然有关于当我们调用一个保证的顺序@AfterViews,-Inject或-Extras注解的方法,有没有保证的顺序调用每一个使用相同的方法@AfterXXX标注。

  • @AfterViews
    该@AfterViews注解表明方法是在视图views绑定之后才会被调用的。

当onCreate()被调用时,@ViewById字段没有被设定。因此,您可以使用@AfterViews方法编写依赖于视图的代码。

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

    @ViewById
    TextView myTextView;

    @AfterViews
    void updateTextWithDate() {
        myTextView.setText("Date: " + new Date());
    }
}
@EActivity(R.layout.main)
public class MyActivity extends Activity {

    @ViewById
    TextView myTextView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // DON'T DO THIS !! It will throw a NullPointerException, myTextView is not set yet.
        // myTextView.setText("Date: " + new Date());
    }
}

@ViewsById

Since AndroidAnnotations 4.0.0

@EActivity
public class MyActivity extends Activity {

  @ViewsById({R.id.myTextView1, R.id.myOtherTextView})
  void setViews(List<TextView> textViews){
    // do something with textViews
  }
}

Event binding

  • @TextChange
@TextChange(R.id.helloTextView)
 void onTextChangesOnHelloTextView(CharSequence text, TextView hello, int before, int start, int count) {
 	// Something Here
 }
 
 @TextChange
 void helloTextViewTextChanged(TextView hello) {
 	// Something Here
 }
 
 @TextChange({R.id.editText, R.id.helloTextView})
 void onTextChangesOnSomeTextViews(TextView tv, CharSequence text) {
 	// Something Here
 }
 
 @TextChange(R.id.helloTextView)
 void onTextChangesOnHelloTextView() {
 	// Something Here
 }

@BeforeTextChange

@BeforeTextChange(R.id.helloTextView)
 void beforeTextChangedOnHelloTextView(TextView hello, CharSequence text, int start, int count, int after) {
 	// Something Here
 }
 
 @BeforeTextChange
 void helloTextViewBeforeTextChanged(TextView hello) {
 	// Something Here
 }
 
 @BeforeTextChange({R.id.editText, R.id.helloTextView})
 void beforeTextChangedOnSomeTextViews(TextView tv, CharSequence text) {
 	// Something Here
 }
 
 @BeforeTextChange(R.id.helloTextView)
 void beforeTextChangedOnHelloTextView() {
 	// Something Here
 }

@AfterTextChange

 @AfterTextChange(R.id.helloTextView)
 void afterTextChangedOnHelloTextView(Editable text, TextView hello) {
 	// Something Here
 }
 
 @AfterTextChange
 void helloTextViewAfterTextChanged(TextView hello) {
 	// Something Here
 }
 
 @AfterTextChange({R.id.editText, R.id.helloTextView})
 void afterTextChangedOnSomeTextViews(TextView tv, Editable text) {
 	// Something Here
 }
 
 @AfterTextChange(R.id.helloTextView)
 void afterTextChangedOnHelloTextView() {
 	// Something Here
 }

@EditorAction

此批注旨在用于接收android.widget.TextView.OnEditorActionListener#onEditorAction(android.widget.TextView, int, android.view.KeyEvent)
在编辑器上执行操作时定义的事件的方法。

该方法可能有多个参数:

  • 一个android.widget.TextView参数知道哪些观点有针对性此事件。
  • 一个int参数来获得actionId。
  • 一个android.view.KeyEvent参数。

方法的返回类型可以是void或boolean。在这种情况下boolean,从带注释的方法返回的值将在生成的侦听器方法中返回(指示事件消耗)。如果带注释的方法是void,则始终true将在侦听器方法中返回(因此将使用该事件)。

  @EditorAction(R.id.helloTextView)
  void onEditorActionsOnHelloTextView(TextView hello, int actionId, KeyEvent keyEvent) {
    // Something Here
  }

  @EditorAction
  void helloTextViewEditorAction(TextView hello) {
    // Something Here
  }

  @EditorAction({R.id.editText, R.id.helloTextView})
  void onEditorActionsOnSomeTextViews(TextView tv, int actionId) {
    // Something Here
  }

  @EditorAction(R.id.helloTextView)
  void onEditorActionsOnHelloTextView() {
    // Something Here
  }


  @EditorAction(R.id.helloTextView)
  boolean onEditorActionsOnHelloTextView() {
    // Something Here
    return false;
  }
  • @Click
@Click(R.id.myButton)
void myButtonWasClicked() {
    [...]
}

@Click
void anotherButton() {
    [...]
}

@Click
void yetAnotherButton(View clickedView) {
    [...]
}

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

Threading

  • @Background
    该@Background注解表明方法将运行一个非UI线程。
void myMethod() {
    someBackgroundWork("hello", 42);
}

@Background
void someBackgroundWork(String aParam, long anotherParam) {
    [...]
}

该方法在单独的线程上执行,但这并不一定意味着将启动新线程,因为我们使用共享的缓存线程池执行器(可以替换)来防止创建过多的线程。

这也意味着两种@Background方法可以并行运行

ID

自AndroidAnnotations 3.0以来

如果要取消后台任务,可以使用该id字段。然后可以通过BackgroundExecutor.cancelAll(“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

Since AndroidAnnotations 3.0

默认情况下,@Background方法是并行处理的。如果希望它们按顺序执行,则可以使用该serial字段。具有相同的所有后台任务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

Since AndroidAnnotations 3.0

如果需要在运行后台方法之前添加延迟,可以使用以下delay参数

@Background(delay=2000)
void doInBackgroundAfterTwoSeconds() {
}
  • @UiThread
    该@UiThread注解表明一个方法将在运行UI线程。
void myMethod() {
    doInUiThread("hello", 42);
}

@UiThread
void doInUiThread(String aParam, long anotherParam) {
    [...]
}

Delay
如果需要在UI线程上运行方法之前添加延迟,可以使用以下delay参数:

@UiThread(delay=2000)
void doInUiThreadAfterTwoSeconds() {
}

Propagation

在3.0之前,@Thread始终在处理程序执行队列中添加带注释的方法调用,以确保在Ui线程中执行。从3.0开始,出于兼容性目的,我们保持相同的行为。

但是,如果要优化UiThread调用,可能需要将propagation值更改为REUSE。在此配置中,如果当前线程已经是Ui线程,则代码将直接调用该方法。如果没有,我们将回到处理程序调用。

如果需要在UI线程上运行方法之前添加延迟,可以使用以下delay参数:

@UiThread(propagation = Propagation.REUSE)
void runInSameThreadIfOnUiThread() {
}

注意:如果与延迟结合使用,传播将被忽略,并且调用将始终在处理程序执行队列中发布。

ID

自AndroidAnnotations 4.0.0起

如果要取消UI线程任务,可以使用该id字段。然后可以通过UiThreadExecutor.cancelAll(“id”);以下方式取消每项任务

void myMethod() {
    someCancellableUiThreadMethod("hello", 42);
    [...]
    UiThreadExecutor.cancelAll("cancellable_task");
}

@UiThread(id="cancellable_task")
void someCancellableUiThreadMethod(String aParam, long anotherParam) {
    [...]
}

@SupposeBackground

自AndroidAnnotations 3.1

注释您的方法以确保从后台线程调用它们(允许)允许的序列号限制。如果未从假定的后台线程调用它,IllegalStateException则将抛出(默认情况下)。允许的IDs可以传递给serial参数,如果没有传递,ID则允许任何。
如果要覆盖在假定的线程上未调用方法时发生的情况,请传递BackgroundExecutor.WrongThreadListenerto 的实例BackgroundExecutor.setWrongThreadListener()。onBgExpected如果在错误的线程上调用带注释的方法,则将调用其方法,或者onWrongBgSerial如果带注释的方法在后台线程上调用但ID 错误,则将调用其方法。

@EBean
public class MyBean {

  @SupposeBackground
  void someMethodThatShouldNotBeCalledFromUiThread() {
  //if this method will be called from the UI-thread an exception will be thrown
  }
  
  @SupposeBackground(serial = {"serial1", "serial2"})
  void someMethodThatShouldBeCalledFromSerial1OrSerial2() {
  //if this method will be called from another thread then a background thread with a
  //serial "serial1" or "serial2", an exception will be thrown
  }
}

@SupposeUiThread

自AndroidAnnotations 3.1

注释您的方法以确保从UI线程调用它们。如果不是,那么IllegalStateException将被抛出(默认情况下)。
如果要覆盖在UI线程上未调用方法时发生的情况,请传递BackgroundExecutor.WrongThreadListenerto 的实例BackgroundExecutor.setWrongThreadListener()。onUiExpected如果在错误的线程上调用带注释的方法,则将调用其方法。

@EBean
public class MyBean {

  @SupposeUiThread
  void someMethodThatShouldBeCalledOnlyFromUiThread() {
  //if this method will be called from a background thread an exception will be thrown
  }

}

点击获取 更多注解使用.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值