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");
}
}