体验AndroidAnnotations

宋典
2023-12-01

1,AndroidAnnotations 配置

    http://www.tuicool.com/articles/aaaiae

2,对比使用前后区别

    http://androidannotations.org/

3,简述工作原理    

@Retention(RetentionPolicy.CLASS)
@Target({java.lang.annotation.ElementType.TYPE})
public @interface EActivity{
 
  public abstract int value();

  public abstract String resName();
}

    利用Java Annotation Processing Tool (APT) 在编译源文件(*.java)之前,通过一个自定义的注解处理器(AnnotationProcessor)解释并处理源文件中的注解,由注解处理器生成 一些新的源文件,字节码文件(*.class),或其他的文本文件,APT也会对新生成源文件进行编译,直到没有新的文件生成。
编译前:

package com.some.company;
@EActivity
public class MyActivity extends Activity {
  // ...
}
编译后:
package com.some.company;
public final class MyActivity_ extends MyActivity {
  // ...
}

所以  AndroidManifest.xml中用到的Activity和Application都要加下划线:xxActivity_,xxApplication_
        

startActivity(this, MyListActivity_.class);
startService(this, MyService_.class);

4,举例说明,该如何使用各个注解


package com.googlecode.androidannotations.helloworldeclipse;
    @EActivity(R.layout.my_activity) //布局文件在这里声明,不用在setContentView  
    public class MyActivity extends Activity {  
      
        @ViewById  //控件这样标注,由于是IOC模式,因此不需要自己实例化  
        EditText myEditText;  
      
        @ViewById(R.id.myTextView) //提供id来生成控件,如果不指定ID,默认以控件名进行查找,如上面的myEditText  
        TextView textView;  
      
        @StringRes(R.string.hello)  //资源,如果字段名和资源命名一直可以省略,如下  
        String helloFormat;  
      
        @ColorRes  
        int androidColor;  
      
        @BooleanRes  
        boolean someBoolean;  
      
        @SystemService  
        NotificationManager notificationManager;  
      
        @SystemService  
        WindowManager windowManager;  
      
        
        public void onBackPressed() {  
            Toast.makeText(this, "Back key pressed!", Toast.LENGTH_SHORT).show();  
        }  
          
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            // windowManager should not be null  
            windowManager.getDefaultDisplay();  
            requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);  
        }  
      
      
        @Click //事件控制,可以以按钮的id作为方法名,同时支持的事件还有onLongClick,onTextChange等  
        void myButtonClicked() {  
            String name = myEditText.getText().toString();  
            setProgressBarIndeterminateVisibility(true);  
            someBackgroundWork(name, 5);  
        }  
      
        @Background //开启新线程后台运行,注意不要引用UI控件,而且返回值类型一定是void  
        void someBackgroundWork(String name, long timeToDoSomeLongComputation) {  
            try {  
                TimeUnit.SECONDS.sleep(timeToDoSomeLongComputation);  
            } catch (InterruptedException e) {  
            }  
      
            String message = String.format(helloFormat, name);  
      
            updateUi(message, androidColor);  
      
            showNotificationsDelayed();  
        }  
      
        @UiThread //UI线程  
        void updateUi(String message, int color) {  
            setProgressBarIndeterminateVisibility(false);  
            textView.setText(message);  
            textView.setTextColor(color);  
        }  
      
        @UiThread(delay=2000)  //可以设置延时时间,以毫秒为单位  
        void showNotificationsDelayed() {  
            Notification notification = new Notification(R.drawable.icon, "Hello !", 0);  
            PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(), 0);  
            notification.setLatestEventInfo(getApplicationContext(), "My notification", "Hello World!", contentIntent);  
            notificationManager.notify(1, notification);  
        }  
      
        @LongClick  
        void startExtraActivity() {  
            Intent intent = new Intent(this, ActivityWithExtra_.class);  
      
            intent.putExtra(ActivityWithExtra.MY_DATE_EXTRA, new Date());  
            intent.putExtra(ActivityWithExtra.MY_STRING_EXTRA, "hello !");  
            intent.putExtra(ActivityWithExtra.MY_INT_EXTRA, 42);  
      
            startActivity(intent);  
        }  
      
        @Click  
        void startListActivity(View v) {  
            startActivity(new Intent(this, MyListActivity_.class));  
        }  
      
        @Touch  
        void myTextView(MotionEvent event) {  
            Log.d("MyActivity", "myTextView was touched!");  
        }  
      
        @Transactional  
        int transactionalMethod(SQLiteDatabase db, int someParam) {  
            //dosomething; 
        }  
      
    }

使用AndroidAnnotations好处就在于使得代码量小而且简洁,使我们更多的关注于业务逻辑而不是页面

一些常用注释的使用方法:
@AfterInject定义的方法在类的构造方法执行后执行
@AfterTextChange定义的方法在TextView及其子类的Text属性改变后执行
@AfterViews定义的方法在setContentView后执行
@Background定义的方法在后台线程执行,开启的线程在线程池中管理
@BeforeTextChange定义的方法在TextView及其子类的Text属性改变前执行
@Click定义点击监听器
@EActivity在Activity中启用Annotations
@EProvider在 ContentProvider中启用Annotations
@EReceive在BroadcastReceiver中启用Annotations
@EService在Service中启用Annotations
@EView在自定义的View的子类中启用Annotations
@Fullscreen全屏

@NoTitle 无标题栏

更多注解的详细用法参见官方网上 Cookbook 及所有 可用的 annotations 列表文档


5,介绍下Spring-Rest-Template的优缺点

    优点:1,AndroidAnnotations框架支持@Rest标签,引入方便,导入jar包即可
             2,Rest支持多种返回类型解析:Json,xml,String,ByteArray,Form,Source,自定义转换器
             3,多种请求方式,可以自定义头信息,可以对请求进行授权
    缺点:1,多次请求无法共享session(可以通过传入自定义的httpclient解决)
             2,无法集中处理返回的Msg对象(统一处理TimeOut和一些异常信息),除非修改源码
             3,无法控制停止已发起的请求
             4,需要引入多个jar包,Spring-android-rest-template.jar,Spring-android-core.jar,
                 Spring-android-auth.jar和jackson-all.jar

    个人认为还是不要用Rest的这套东西,网络请求还是我们自己写比较合适

补充说明:

    1,onSaveInstanceState的使用
        保存activity暂时的状态(保存类成员变量关联着UI的值,例如:某个处于选中状态下RadioButton的ID),
        便于恢复
    2,使用@EBean的JavaBean,能直接取到调用他的Context,并且支持@ViewById标签找到控件,因此,
       构造方法传过来的参数可以少很多。
       例如:
        

@EBean
public class Student {

	//RootContext能取到调用该Bean的Context,构造方法不再需要传Context参数
	@RootContext
	Context context;

	@RootContext
	MainActivity activity;

       //ViewById也能在这里直接使用
	@ViewById
	TextView tv;

       public void Toast(){
	    Toast.makeText(context, "在Ebean中调用", Toast.LENGTH_LONG).show();
	}

     //后台线程执行
	@Background
	public void backThread(){
		
            //dosomething
	    activity.updateTv(i);

	    //更新UI,调用在UI线程执行的方法
	    updateTv(i);
		
	}

       //UiThread在UI线程执行
	@UiThread
	public void updateTv(int i){
	    tv.setText(String.valueOf(i));
	}

       //AfterInject在构造方法执行完成后执行
	@AfterInject
	public void doSomethingAfterInject(){
	    System.out.println("Student AfterInject");
	}
 
}

转载于:https://my.oschina.net/u/162503/blog/175361

 类似资料: