AndroidAnnotation4.0发布已经一个多月了,今天抽空看了下,改变还是挺多的,做下笔记吧。
主要变化:
- 去除了 @NoTitle注解 和对 ActionBarSherlock 的支持
可以这样替代
@WindowFeature( Window.FEATURE_NO_TITLE)
@EActivity
public class MyActivity extends Activity {}
- 在 Fragment#onDestroyView() 中清空注入的View避免内存泄露
- @ReveiverAction 注解中不将方法名作为action名称,所以今后得指定了
- 去掉了 @OrmLiteDao 注解中的 model 参数
- 可以取消 @UiThread 注解的任务了,这个比较给力
和取消后台线程基本一致
UiThreadExecutor.cancelAll("cancellable_task");
- @Extra 和@InstanceState 支持Parceler 参数
- 添加了 @PageChange
- 添加了 @IgnoreWhen ,但是去掉了 @IgnoreWhenDetached
- @FragmentByXXX 会注入child Fragment
- Activity Intent builder支持动画了 withAnimations()
- @NonConfigurationInstance 先于 @Bean 注入
- Add type() , category() and data() methods to IntentBuilder
- Deprecate @HttpsClient
主要变化就这些,变化总体来说还是蛮大的,优化很给力!
需要特别说明:
Starting with Android Annotations 4.0.0 we no longer override onNewIntent() and you have to override it by yourself if needed.
1.配置说明
之前写了Eclipse下的配置,今天写一下as下的配置:
apply plugin: 'com.android.application'
apply plugin: 'android-apt'
def AAVersion = 'XXX'
dependencies {
apt "org.androidannotations:androidannotations:$AAVersion"
compile "org.androidannotations:androidannotations-api:$AAVersion"
}
apt {
arguments {
androidManifestFile variant.outputs[0]?.processResources?.manifestFile
// if you have multiple outputs (when using splits), you may want to have other index than 0
// you should set your package name here if you are using different application IDs
// resourcePackageName "your.package.name"
// You can set optional annotation processing options here, like these commented options:
// logLevel 'INFO'
// logFile '/var/log/aa.log'
}
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
// replace with the current version of the Android plugin
classpath 'com.android.tools.build:gradle:1.5.0'
// replace with the current version of the android-apt plugin
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
repositories {
mavenCentral()
mavenLocal()
}
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
minSdkVersion 9
targetSdkVersion 23
}
}
2主要变化
1.ViewPager的PageChangeEvents
@PageScrollStateChanged
对应 android.support.v4.view.ViewPager.OnPageChangeListener.onPageScrollStateChanged(int state) ,这个注解的方法可以包含以下两个参数(也可以不包含参数):
- android.support.v4.view.ViewPager
- int型参数:表示新的滚动状态
@PageScrollStateChanged(R.id.viewpager)
void onPageScrollStateChanged(ViewPager view, int state) {
// Something Here
}
@PageScrollStateChanged
void viewPager(ViewPager view) {
// Something Here
}
@PageScrollStateChanged({R.id.viewPager1, R.id.viewPager2})
void onPageScrollStateChangedOnMultipleViewPager(ViewPager v, int anything) {
// Something Here
}
@PageScrollStateChanged(R.id.viewpager)
void onPageScrollStateChangedNoParam() {
// Something Here
}
@PageScrolled
对应 android.support.v4.view.ViewPager.OnPageChangeListener.onPageScrolled(int position, float positionOffset, int positionOffsetPixels) ,这个注解的方法可以包含以下几种参数,注意顺序不要乱(参数仍然为可选):
- android.support.v4.view.ViewPager
- 一个int position参数表示当前正在展示的界面,如果positionOffset 是非0的,那么position+1 界面就会展示出来
- 一个取值范围是[0,1)的float参数表示当前页面的偏移
4.一个int positionOffsetPixels参数表示像素偏移
@PageScrolled(R.id.viewpager)
void onPageScrolled(ViewPager view, int position, float positionOffset, int positionOffsetPixels) {
// Something Here
}
@PageScrolled
void viewPager(ViewPager view) {
// Something Here
}
@PageScrolled({R.id.viewPager1, R.id.viewPager2})
void onPageScrolledOnMultipleViewPager(ViewPager v, int position) {
// Something Here
}
@PageScrolled(R.id.viewpager)
void onPageScrolledNoParam() {
// Something Here
}
@PageSelected
对应 android.support.v4.view.ViewPager.OnPageChangeListener.onPageSelected(int position) ,可以包含两个参数,同样为可选:
@PageSelected(R.id.viewpager)
void onPageSelected(ViewPager view, int position) {
// Something Here
}
@PageSelected
void viewPager(ViewPager view) {
// Something Here
}
@PageSelected({R.id.viewPager1, R.id.viewPager2})
void onPageSelectedOnMultipleViewPager(ViewPager v, int position) {
// Something Here
}
@PageSelected(R.id.viewpager)
void onPageSelectedNoParam() {
// Something Here
}
2.Activity转场动画
MyListActivity_.intent(context).start().withAnimation(enterAnimRes, exitAnimRes));
3.方法依赖注入
一定程度上可以避免内存泄露与节省内存占用,也比较实用!
在自定义类中:
@EBean
public class MyBean {
@App
void setApplication(MyApplication application){
// do something with application
}
}
注入Fragment:
@EActivity(R.layout.fragments)
public class MyFragmentActivity extends FragmentActivity {
@FragmentById
void setOneFragmentById(MyFragment myFragmentId){
// do something with myFragmentId
}
void setMultipleFragmentsById(@FragmentById MyFragment myFragmentId, @FragmentById(R.id.myFragment) MyFragment myFragmentId2){
// do something with myFragmentId and myFragmentId2
}
@FragmentByTag
void setOneFragmentByTag(MyFragment myFragmentTag){
// do something with myFragmentTag
}
void setMultipleFragmentsByTag(@FragmentByTag MyFragment myFragmentTag, @FragmentByTag("myFragmentTag") MyFragment myFragmentTag2){
// do something with myFragmentTag and myFragmentTag2
}
}
fragment也支持参数方法注入:
@EFragment
public class MyFragment extends Fragment {
@FragmentArg
void setOneFragmentArg(@FragmentArg("myStringArgument") String myMessage){
// do something with myMessage
}
void setMultipleFragmentArgs(@FragmentArg String anotherStringArgument, @FragmentArg("myDateExtra") Date myDateArgument){
// do something with anotherStringArgument and myDateArgument
}
}
注入View
@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
}
}
@EActivity
public class MyActivity extends Activity {
@ViewsById({R.id.myTextView1, R.id.myOtherTextView})
void setViews(List<TextView> textViews){
// do something with textViews
}
}
资源注入:
This works for all @*Res annotations.
@EActivity
public class MyActivity extends Activity {
@ColorRes(R.color.backgroundColor)
void setOneResource(int someColor){
// do something with someColor
}
void setMultipleBeans(@StringRes(R.string.hello) String myHelloString, @StringRes String hello){
// do something with myHelloString and hello
}
}
Extra注入:
@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
}
}
SystemService 注入:
@EActivity
public class MyActivity extends Activity {
@SystemService
void setNotificationManager(NotificationManager notificationManager){
// do something with notificationManager
}
void setMultipleServices(@SystemService NotificationManager notificationManager, @SystemService AudioManager audioManager){
// do something with notificationManager and audioManager
}
}
KeyEvents
自4.0开始加入。
• @KeyDown
• @KeyUp
• @KeyLongPress
• @KeyMultiple
@EActivity
public class MyActivity extends Activity {
@KeyDown
void enterPressed() {
//...
}
@KeyUp(KeyEvent.KEYCODE_ESCAPE)
boolean handleEscapeActionUpEvent() {
//...
return false;
}
@KeyLongPress({ KeyEvent.KEYCODE_F, KeyEvent.KEYCODE_G })
void fOrGKeyLongPress(KeyEvent keyEvent) {
//...
}
}
@KeyMultiple需要说明下可以传递的参数:
•a int or Integer (the count of action repeates) and/or
•a KeyEvent (the event that was triggered).
@EActivity
public class MyActivity extends Activity {
@KeyMultiple
void onEnterPressed() {
//...
}
@KeyMultiple(KeyEvent.KEYCODE_ESCAPE)
boolean handleEscapeActionMultipleEvent(int count) {
//...
return false;
}
@KeyMultiple({ KeyEvent.KEYCODE_F, KeyEvent.KEYCODE_G })
void fOrGKeyWasMultiplePressed(int count, KeyEvent keyEvent) {
//...
}
}
ViewChangeEvents
1.@FocusChange
注意,从4.0开始,只要传入View的子类就可以
@FocusChange(R.id.helloTextView)
void focusChangedOnHelloTextView(View hello, boolean hasFocus) {
// Something Here
}
@FocusChange
void helloTextViewFocusChanged(View hello) {
// Something Here
}
@FocusChange({R.id.editText, R.id.helloTextView})
void focusChangedOnSomeTextViews(View hello, boolean hasFocus) {
// Something Here
}
@FocusChange(R.id.helloTextView)
void focusChangedOnHelloTextView() {
// Something Here
}
2.@CheckedChange
用来替代
android.widget.CompoundButton.OnCheckedChangeListener.onCheckedChanged(CompoundButton buttonView, boolean isChecked)
看一下使用:
只要是CompoundButton 的子类都可以使用
@CheckedChange(R.id.helloCheckBox)
void checkedChangeOnHelloCheckBox(CompoundButton hello, boolean isChecked) {
// Something Here
}
@CheckedChange
void helloCheckBoxCheckedChanged(CompoundButton hello) {
// Something Here
}
@CheckedChange({R.id.aCheckBox, R.id.helloCheckBox})
void checkedChangedOnSomeCheckBoxs(CompoundButton hello, boolean isChecked) {
// Something Here
}
@CheckedChange(R.id.helloCheckBox)
void checkedChangedOnHelloCheckBox() {
// Something Here
}
@IgnoreWhen
避免fragment后台进行耗时操作时activity已经摧毁的通信异常,目前仅支持两种状态,如下:
@EFragment
public class LoaderFragment extends Fragment {
[...]
@UiThread
@IgnoreWhen(IgnoreWhen.State.DETACHED)
void killActivity() {
getActivity().finish();
}
@IgnoreWhen(IgnoreWhen.State.VIEW_DESTROYED)
void setViewBackground(int resid) {
view.setBackgroundResource(resid);
}
4.0的新福利
TextChangeEvents允许传入TextView的子类了,如EditText
ClickEvents允许传入任意View的子类了
现在可以停止UIThread注解的方法了:
void myMethod() {
someCancellableUiThreadMethod("hello", 42);
[...]
UiThreadExecutor.cancelAll("cancellable_task");
}
@UiThread(id="cancellable_task")
void someCancellableUiThreadMethod(String aParam, long anotherParam) {
[...]
}
其他的
1.@EReceiver在kotlin中写法:
open class WifiReceiver : AbstractBroadcastReceiver() {
@ReceiverAction(actions = arrayOf(WifiManager.NETWORK_STATE_CHANGED_ACTION))
fun netAction(intent: Intent) {
// ...
}
}