newAsyncTask<Void,Void,Void>(){//doInBackground is already annotated with @WorkerThread@OverrideprotectedVoiddoInBackground(Void...params){returnnull;updateViews();//error}};@UiThreadpublicvoidupdateViews(){Log.i(LOGTAG,"updateViews ThreadInfo="+Thread.currentThread());}
classExampleActivityextendsActivity{@BindView(R.id.user)EditTextusername;@BindView(R.id.pass)EditTextpassword;@BindString(R.string.login_error)StringloginErrorMessage;@OnClick(R.id.submit)voidsubmit(){// TODO call server...}@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.simple_activity);ButterKnife.bind(this);// TODO Use fields...}}
@NonNull@CheckResult@UiThreadstaticViewBinder<Object>getViewBinder(@NonNullObjecttarget){Class<?>targetClass=target.getClass();if(debug)Log.d(TAG,"Looking up view binder for "+targetClass.getName());returnfindViewBinderForClass(targetClass);}@NonNull@CheckResult@UiThreadprivatestaticViewBinder<Object>findViewBinderForClass(Class<?>cls){//如果内存集合BINDERS中包含,则不再查找ViewBinder<Object>viewBinder=BINDERS.get(cls);if(viewBinder!=null){if(debug)Log.d(TAG,"HIT: Cached in view binder map.");returnviewBinder;}StringclsName=cls.getName();if(clsName.startsWith("android.")||clsName.startsWith("java.")){if(debug)Log.d(TAG,"MISS: Reached framework class. Abandoning search.");returnNOP_VIEW_BINDER;}//noinspection TryWithIdenticalCatches Resolves to API 19+ only type.try{//使用反射创建实例Class<?>viewBindingClass=Class.forName(clsName+"_ViewBinder");//noinspection uncheckedviewBinder=(ViewBinder<Object>)viewBindingClass.newInstance();if(debug)Log.d(TAG,"HIT: Loaded view binder class.");}catch(ClassNotFoundExceptione){//如果没有找到,对父类进行查找if(debug)Log.d(TAG,"Not found. Trying superclass "+cls.getSuperclass().getName());viewBinder=findViewBinderForClass(cls.getSuperclass());}catch(InstantiationExceptione){thrownewRuntimeException("Unable to create view binder for "+clsName,e);}catch(IllegalAccessExceptione){thrownewRuntimeException("Unable to create view binder for "+clsName,e);}//加入内存集合,便于后续的查找BINDERS.put(cls,viewBinder);returnviewBinder;}
➜androidannotationsamplejavap-cMainActivity_ViewBindingWarning:BinaryfileMainActivity_ViewBindingcontainscom.example.admin.androidannotationsample.MainActivity_ViewBindingCompiledfrom"MainActivity_ViewBinding.java"publicclasscom.example.admin.androidannotationsample.MainActivity_ViewBinding<Textendscom.example.admin.androidannotationsample.MainActivity>implementsbutterknife.Unbinder{protectedTtarget;publiccom.example.admin.androidannotationsample.MainActivity_ViewBinding(T,butterknife.internal.Finder,java.lang.Object);Code:0:aload_01:invokespecial#1// Method java/lang/Object."<init>":()V4:aload_05:aload_16:putfield#2// Field target:Lcom/example/admin/androidannotationsample/MainActivity;9:aload_110:aload_211:aload_3//调用Finder.findRequireViewAsType找到View,并进行类型转换,并复制给MainActivity中对一个的变量12:ldc#4// int 213142741214:ldc#5// String field 'myTextView'16:ldc#6// class android/widget/TextView// 内部实际调用了findViewById18:invokevirtual#7// Method butterknife/internal/Finder.findRequiredViewAsType:(Ljava/lang/Object;ILjava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;21:checkcast#6// class android/widget/TextView24:putfield#8// Field com/example/admin/androidannotationsample/MainActivity.myTextView:Landroid/widget/TextView;27:returnpublicvoidunbind();Code:0:aload_01:getfield#2// Field target:Lcom/example/admin/androidannotationsample/MainActivity;4:astore_15:aload_16:ifnonnull199:new#9// class java/lang/IllegalStateException12:dup13:ldc#10// String Bindings already cleared.15:invokespecial#11// Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V18:athrow19:aload_120:aconst_null// 解除绑定,设置对应的变量为null21:putfield#8// Field com/example/admin/androidannotationsample/MainActivity.myTextView:Landroid/widget/TextView;24:aload_025:aconst_null26:putfield#2// Field target:Lcom/example/admin/androidannotationsample/MainActivity;29:return}
packagebutterknife.internal;importandroid.app.Activity;importandroid.app.Dialog;importandroid.content.Context;importandroid.support.annotation.IdRes;importandroid.view.View;@SuppressWarnings("UnusedDeclaration")// Used by generated code.publicenumFinder{VIEW{@OverridepublicViewfindOptionalView(Objectsource,@IdResintid){return((View)source).findViewById(id);}@OverridepublicContextgetContext(Objectsource){return((View)source).getContext();}@OverrideprotectedStringgetResourceEntryName(Objectsource,@IdResintid){finalViewview=(View)source;// In edit mode, getResourceEntryName() is unsupported due to use of BridgeResourcesif(view.isInEditMode()){return"<unavailable while editing>";}returnsuper.getResourceEntryName(source,id);}},ACTIVITY{@OverridepublicViewfindOptionalView(Objectsource,@IdResintid){return((Activity)source).findViewById(id);}@OverridepublicContextgetContext(Objectsource){return(Activity)source;}},DIALOG{@OverridepublicViewfindOptionalView(Objectsource,@IdResintid){return((Dialog)source).findViewById(id);}@OverridepublicContextgetContext(Objectsource){return((Dialog)source).getContext();}};//查找对应的Finder,如上面的ACTIVITY, DIALOG, VIEWpublicabstractViewfindOptionalView(Objectsource,@IdResintid);publicfinal<T>TfindOptionalViewAsType(Objectsource,@IdResintid,Stringwho,Class<T>cls){Viewview=findOptionalView(source,id);returncastView(view,id,who,cls);}publicfinalViewfindRequiredView(Objectsource,@IdResintid,Stringwho){Viewview=findOptionalView(source,id);if(view!=null){returnview;}Stringname=getResourceEntryName(source,id);thrownewIllegalStateException("Required view '"+name+"' with ID "+id+" for "+who+" was not found. If this view is optional add '@Nullable' (fields) or '@Optional'"+" (methods) annotation.");}//来自ViewBinding的调用publicfinal<T>TfindRequiredViewAsType(Objectsource,@IdResintid,Stringwho,Class<T>cls){Viewview=findRequiredView(source,id,who);returncastView(view,id,who,cls);}publicfinal<T>TcastView(Viewview,@IdResintid,Stringwho,Class<T>cls){try{returncls.cast(view);}catch(ClassCastExceptione){Stringname=getResourceEntryName(view,id);thrownewIllegalStateException("View '"+name+"' with ID "+id+" for "+who+" was of the wrong type. See cause for more info.",e);}}@SuppressWarnings("unchecked")// That's the point.publicfinal<T>TcastParam(Objectvalue,Stringfrom,intfromPos,Stringto,inttoPos){try{return(T)value;}catch(ClassCastExceptione){thrownewIllegalStateException("Parameter #"+(fromPos+1)+" of method '"+from+"' was of the wrong type for parameter #"+(toPos+1)+" of method '"+to+"'. See cause for more info.",e);}}protectedStringgetResourceEntryName(Objectsource,@IdResintid){returngetContext(source).getResources().getResourceEntryName(id);}publicabstractContextgetContext(Objectsource);}
Otto
Otto Bus 是一个专为Android改装的Event Bus,在很多项目中都有应用.由Square开源共享.
publicvoidregister(Objectobject){if(object==null){thrownewNullPointerException("Object to register must not be null.");}enforcer.enforce(this);//查找object中的SubscriberMap<Class<?>,Set<EventHandler>>foundHandlersMap=handlerFinder.findAllSubscribers(object);for(Class<?>type:foundHandlersMap.keySet()){Set<EventHandler>handlers=handlersByType.get(type);if(handlers==null){//concurrent put if absentSet<EventHandler>handlersCreation=newCopyOnWriteArraySet<EventHandler>();handlers=handlersByType.putIfAbsent(type,handlersCreation);if(handlers==null){handlers=handlersCreation;}}finalSet<EventHandler>foundHandlers=foundHandlersMap.get(type);if(!handlers.addAll(foundHandlers)){thrownewIllegalArgumentException("Object already registered.");}}for(Map.Entry<Class<?>,Set<EventHandler>>entry:foundHandlersMap.entrySet()){Class<?>type=entry.getKey();EventProducerproducer=producersByType.get(type);if(producer!=null&&producer.isValid()){Set<EventHandler>foundHandlers=entry.getValue();for(EventHandlerfoundHandler:foundHandlers){if(!producer.isValid()){break;}if(foundHandler.isValid()){dispatchProducerResultToHandler(foundHandler,producer);}}}}}
/** This implementation finds all methods marked with a {@link Subscribe} annotation. */staticMap<Class<?>,Set<EventHandler>>findAllSubscribers(Objectlistener){Class<?>listenerClass=listener.getClass();Map<Class<?>,Set<EventHandler>>handlersInMethod=newHashMap<Class<?>,Set<EventHandler>>();Map<Class<?>,Set<Method>>methods=SUBSCRIBERS_CACHE.get(listenerClass);if(null==methods){methods=newHashMap<Class<?>,Set<Method>>();loadAnnotatedSubscriberMethods(listenerClass,methods);}if(!methods.isEmpty()){for(Map.Entry<Class<?>,Set<Method>>e:methods.entrySet()){Set<EventHandler>handlers=newHashSet<EventHandler>();for(Methodm:e.getValue()){handlers.add(newEventHandler(listener,m));}handlersInMethod.put(e.getKey(),handlers);}}returnhandlersInMethod;}
以上就是关于Android中注解的一些总结,文章部分内容参考自 Support Annotations ,希望能帮助大家对注解有基础的认识,并运用到实际的日常开发之中.