java 自定义 编译校验编译条件中extraData需要怎么写

谁知道这个自定义函数什么意思?麻烦讲一下,参数含义?_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
谁知道这个自定义函数什么意思?麻烦讲一下,参数含义?
function submitAjaxForm(strFormId, fnCallBack, vStrURL, vExtraData, objIdLoadingDiv, vDataType){
var theForm = $('#' + strFormId);
if(!theForm || !fnCallBack){
var strMethod = (theForm.attr('method')) ? theForm.at...
我有更好的答案
.这是一个AJAX异步请求的自定义函数参数是strFormId表单idfnCallBack数据返回后要执行的函数名,即回调函数。vStrURL请求的地址vExtraData要提交的数据objIdLoadingDiv请求进行时的div id.vDataType返回的数据格式。默认为html。 从写法上来看,这个自定义的函数依赖Jquery,即我们常见的loading。一般为js处理返回的数据的函数
为您推荐:
其他类似问题
您可能关注的内容
函数的相关知识
等待您来回答STM32(7)
写程序的过程中,会有不少的条件编译命令,但是条件编译过多会导致忘记了定义那些条件,排查起来也非常麻烦,有没有什么好的方法来查找是否是否有该定义呢?
答案是有的:那就# warning
和# error;具体如下:
# warning "this is a warning message test"
# error "this is a error message test"
当程序编译到这个里的时候,会在编译输出窗口打印出该信息
这样我们就可以在条件编译命令的地方这么写
#ifndef TEST
# warning "TEST is not defined"
DoSomthing();
# warning "TEST is defined"
DoSomthing();
编译结果如下:
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3193次
排名:千里之外
原创:12篇
(3)(2)(1)(1)(6)(2)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'整理(17)
自定义View控件-工具类(1)
前日,一个朋友问我有没有好看的弹窗,功能不需要太难,说了一点需求,图:
然后我就写了个Demo给他。
Activity的弹窗各种各样。很早就有,但是有的太过于单调,样式也不好看,有的自定义起来非常繁琐。
我结合自定义Activity主题style,写了个很简单的Fragment组合应用。
前提说明:
——开发工具:Android studio64位 3.0 版本
——声明控件使用butterknife
(build.gradle文件里dependencies{}内直接加入compile ‘com.jakewharton:butterknife:8.6.0’)
——模拟器版本:逍遥模拟器Android 4.3
——Demo中有些地方引用了自定义的color和style(路径:src-mian-res-values)
——AndroidManifest.xml 里对应的CustomPopwindowActivity类(弹窗类)自定义了主题
android:name=".CustomPopwindowActivity"
android:theme="@style/bottom_dialog"&&
这里注意一下:
布局文件为了显示效果写了很多无用的控件,主要是为了体现效果,主要关键地方,我会单独描述出来
三段式介绍:主要内容摘要介绍,主要代码块粘贴,文末有Demo下载
先上个比较粗糙的效果图:
然后上干货:
主要代码块:
* 自定义弹窗
* 声明控件用的是butterknife,添加方法:
* app的build.gradle里面
* dependencies { }括号里添加
* annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'
* compile 'com.jakewharton:butterknife:8.6.0'
* 用什么声明随意,根据自己要求就行
public class MainActivity extends AppCompatActivity {
@BindView(R.id.button)
@BindView(R.id.button2)
Button button2;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
@OnClick({R.id.button, R.id.button2})
public void onClick(View view) {
switch (view.getId()) {
case R.id.button:
Bundle bundle = new Bundle();
bundle.putInt("key", 1);
Intent intent = new Intent(MainActivity.this, CustomPopwindowActivity.class);
intent.putExtras(bundle);
startActivity(intent);
case R.id.button2:
Bundle bundle2 = new Bundle();
bundle2.putInt("key", 2);
Intent intent2 = new Intent(MainActivity.this, CustomPopwindowActivity.class);
intent2.putExtras(bundle2);
startActivity(intent2);
主页面 布局:
xmlns:android="/apk/res/android"
xmlns:tools="/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.individual.wzq.custompopwindow.MainActivity"&
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/colorAccent"
android:text="这个是底面"
android:textSize="35sp" /&
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击弹出窗口001" /&
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击弹出窗口002" /&
第二个Activity页面:
* 显示的弹窗主页面
* 在AndroidManifest.xml里,
* CustomPopwindowActivity的添加自定义主题样式,自定义一些style属性(在src-main-res-values-style里)
public class CustomPopwindowActivity extends AppCompatActivity {
@BindView(R.id.body)
private int
BaseFragment baseF
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_popwindow);
ButterKnife.bind(this);
getData();
Window dialogWindow = getWindow();
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.MATCH_PARENT;
dialogWindow.setAttributes(lp);
addFragment();
private void getData() {
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
type = bundle.getInt("key", 1);
private void addFragment() {
switch (type) {
baseFragment = new NewFragment();
baseFragment = new NewFragment2();
getSupportFragmentManager().beginTransaction().replace(R.id.body, baseFragment).commit();
第二个Activity 布局文件:
&?xml version="1.0" encoding="utf-8"?&
xmlns:android="/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/half10_transparent"
android:focusable="true"
android:focusableInTouchMode="true"&
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"&
android:id="@+id/body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:transitionName="EditModel"&&
内嵌的Fragment第一个:
* 继承父类BaseFragment(用于写一些公共的方法和资源)
* 根据自己需求,编写本页面需要的样式和功能
public class NewFragment extends BaseFragment {
@BindView(R.id.radioButton1)
RadioButton radioButton1;
@BindView(R.id.radioButton2)
RadioButton radioButton2;
@BindView(R.id.radioButton3)
RadioButton radioButton3;
@BindView(R.id.radioButton4)
RadioButton radioButton4;
@BindView(R.id.button2)
Button button2;
@BindView(R.id.bottomView)
LinearLayout bottomV
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.add_new_expect_layout, null);
ButterKnife.bind(this, view);
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
getActivity().finish();
public void onDestroyView() {
super.onDestroyView();
第一个Fragment布局文件:
&?xml version="1.0" encoding="utf-8"?&
xmlns:android="/apk/res/android"
android:id="@+id/bottomView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical"&
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="退款原因" /&
android:layout_width="match_parent"
android:layout_height="wrap_content"&
android:id="@+id/radioButton1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RadioButton" /&
android:id="@+id/radioButton2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RadioButton" /&
android:id="@+id/radioButton3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RadioButton" /&
android:id="@+id/radioButton4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="RadioButton" /&
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="关 闭"
android:textSize="25sp" /&
内嵌的Fragment第二个:
* 继承父类BaseFragment(用于写一些公共的方法和资源)
* 根据自己需求,编写本页面需要的样式和功能
public class NewFragment2 extends BaseFragment {
@BindView(R.id.button2)
Button button2;
@BindView(R.id.bottomView)
LinearLayout bottomV
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.add_new_expect_layout2, null);
ButterKnife.bind(this, view);
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
getActivity().finish();
public void onDestroyView() {
super.onDestroyView();
第二个Fragment布局文件:
&?xml version="1.0" encoding="utf-8"?&
xmlns:android="/apk/res/android"
android:id="@+id/bottomView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical"&
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="另一个窗口"
android:textSize="30sp" /&
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="这里可以的输入内容" /&
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" /&
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" /&
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" /&
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" /&
android:id="@+id/button2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="关 闭"
android:textSize="25sp" /&
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:22955次
排名:千里之外
原创:32篇
(1)(3)(1)(4)(4)(6)(5)(10)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'自定义注解 - CSDN博客
自定义注解
注解是我们经常接触的技术,Java有注解,Android也有注解,本文将试图介绍Android中的注解,以及ButterKnife和Otto这些基于注解的库的一些工作原理.
归纳而言,Android中的注解大概有以下好处
提高我们的开发效率更早的发现程序的问题或者错误更好的增加代码的描述能力更加利于我们的一些规范约束提供解决问题的更优解
默认情况下,Android中的注解包并没有包括在framework中,它独立成一个单独的包,通常我们需要引入这个包.
dependencies {
compile 'com.android.support:support-annotations:22.2.0'
但是如果我们已经引入了&appcompat&则没有必要再次引用&support-annotations&,因为&appcompat&默认包含了对其引用.
在最早的时候,当我们想要做一些值得限定实现枚举的效果,通常是
定义几个常量用于限定从上面的常量选取值进行使用
一个比较描述上面问题的示例代码如下
public static final int COLOR_RED = 0;
public static final int COLOR_GREEN = 1;
public static final int COLOR_YELLOW = 2;
public void setColor(int color) {
setColor(COLOR_RED)
然而上面的还是有不尽完美的地方
setColor(COLOR_RED)&与&setColor(0)&效果一样,而后者可读性很差,但却可以正常运行setColor方法可以接受枚举之外的值,比如&setColor(3)&,这种情况下程序可能出问题
一个相对较优的解决方法就是使用Java中的Enum.使用枚举实现的效果如下
public enum ColorEmun {
public void setColorEnum(ColorEmun colorEnum) {
setColorEnum(ColorEmun.GREEN);
然而Enum也并非最佳,Enum因为其相比方案一的常量来说,占用内存相对大很多而受到曾经被Google列为不建议使用,为此Google特意引入了一些相关的注解来替代枚举.
Android中新引入的替代枚举的注解有&IntDef&和&StringDef&,这里以&IntDef&做例子说明一下.
public class Colors {
@IntDef({RED, GREEN, YELLOW})
@Retention(RetentionPolicy.SOURCE)
public @interface LightColors{}
public static final int RED = 0;
public static final int GREEN = 1;
public static final int YELLOW = 2;
声明必要的int常量声明一个注解为LightColors使用@IntDef修饰LightColors,参数设置为待枚举的集合使用@Retention(RetentionPolicy.SOURCE)指定注解仅存在与源码中,不加入到class文件中
Null相关的注解
和Null相关的注解有两个
@Nullable 注解的元素可以是Null
@NonNull 注解的元素不能是Null
上面的两个可以修饰如下的元素
成员属性方法参数方法的返回值
private String obtainReferrerFromIntent(@NonNull Intent intent) {
return intent.getStringExtra(&apps_referrer&);
NonNull检测生效的条件
显式传入null在调用方法之前已经判断了参数为null时
setReferrer(null);
String referrer = getIntent().getStringExtra(&apps_referrer&);
setReferrer(referrer);
String referrer = getIntent().getStringExtra(&apps_referrer&);
if (referrer == null) {
setReferrer(referrer);
private void setReferrer(@NonNull String referrer) {
区间范围注解
Android中的IntRange和FloatRange是两个用来限定区间范围的注解,
float currentP
public void setCurrentProgress(@FloatRange(from=0.0f, to=1.0f) float progress) {
currentProgress =
如果我们传入非法的值,如下所示
setCurrentProgress(11);
就会得到这样的错误
Value must be &=0.0 and (was 11)
长度以及数组大小限制
限制字符串的长度
private void setKey(@Size(6) String key) {
限定数组集合的大小
private void setData(@Size(max = 1) String[] data) {
setData(new String[]{&b&, &a&});
限定特殊的数组长度,比如3的倍数
private void setItemData(@Size(multiple = 3) String[] data) {
在Android中,有很多场景都需要使用权限,无论是Marshmallow之前还是之后的动态权限管理.都需要在manifest中进行声明,如果忘记了,则会导致程序崩溃. 好在有一个注解能辅助我们避免这个问题.使用RequiresPermission注解即可.
@RequiresPermission(Manifest.permission.SET_WALLPAPER)
public void changeWallpaper(Bitmap bitmap) throws IOException {
在Android中几乎所有的资源都可以有对应的资源id.比如获取定义的字符串,我们可以通过下面的方法
public String getStringById(int stringResId) {
return getResources().getString(stringResId);
使用这个方法,我们可以很容易的获取到定义的字符串,但是这样的写法也存在着风险.
getStringById(R.mipmap.ic_launcher)
如果我们在不知情或者疏忽情况下,传入这样的值,就会出现问题. 但是如果我们使用资源相关的注解修饰了参数,就能很大程度上避免错误的情况.
public String getStringById(@StringRes
int stringResId) {
return getResources().getString(stringResId);
在Android中资源注解如下所示
AnimResAnimatorResAnyResArrayResAttrResBoolResColorResDimenResDrawableResFractionResIdResIntegerResInterpolatorResLayoutResMenuResPluralsResRawResStringResStyleResStyleableResTransitionResXmlRes
Color值限定
上面部分提到了&ColorRes&,用来限定颜色资源id,这里我们将使用&ColorInt&,一个用来限定Color值的注解.
在较早的TextView的setTextColor是这样实现的.
public void setTextColor(int color) {
mTextColor = ColorStateList.valueOf(color);
updateTextColors();
然而上面的方法在调用时常常会出现这种情况
myTextView.setTextColor(R.color.colorAccent);
如上,如果传递过去的参数为color的资源id就会出现颜色取错误的问题,这个问题在过去还是比较严重的.好在&ColorInt&出现了,改变了这一问题.
public void setTextColor(@ColorInt int color) {
mTextColor = ColorStateList.valueOf(color);
updateTextColors();
当我们再次传入Color资源值时,就会得到错误的提示.
CheckResult
这是一个关于返回结果的注解,用来注解方法,如果一个方法得到了结果,却没有使用这个结果,就会有错误出现,一旦出现这种错误,就说明你没有正确使用该方法。
@CheckResult
public String trim(String s) {
return s.trim();
Android中提供了四个与线程相关的注解
@UiThread,通常可以等同于主线程,标注方法需要在UIThread执行,比如View类就使用这个注解@MainThread 主线程,经常启动后创建的第一个线程@WorkerThread 工作者线程,一般为一些后台的线程,比如AsyncTask里面的doInBackground就是这样的.@BinderThread 注解方法必须要在BinderThread线程中执行,一般使用较少.
new AsyncTask&Void, Void, Void&() {
protected Void doInBackground(Void... params) {
return null;
updateViews();
public void updateViews() {
Log.i(LOGTAG, &updateViews ThreadInfo=& + Thread.currentThread());
注意,这种情况下不会出现错误提示
new Thread(){
public void run() {
super.run();
updateViews();
}.start();
虽然updateViews会在一个新的工作者线程中执行,但是在compile时没有错误提示.
因为它的判断依据是,如果updateView的线程注解(这里为@UiThread)和run(没有线程注解)不一致才会错误提示.如果run方法没有线程注解,则不提示.
重写的方法必须要调用super方法
使用这个注解,我们可以强制方法在重写时必须调用父类的方法 比如Application的&onCreate&,&onConfigurationChanged&等.
在Android编译生成APK的环节,我们通常需要设置minifyEnabled为true实现下面的两个效果
混淆代码删除没有用的代码
但是出于某一些目的,我们需要不混淆某部分代码或者不删除某处代码,除了配置复杂的Proguard文件之外,我们还可以使用@Keep注解 .
public static int getBitmapWidth(Bitmap bitmap) {
return bitmap.getWidth();
ButterKnife
ButterKnife是一个用来绑定View,资源和回调的提高效率的工具.作者为Jake Wharton. ButterKnife的好处
使用BindView替代繁琐的findViewById和类型转换使用OnClick注解方法来替换显式声明的匿名内部类使用BindString,BindBool,BindDrawable等注解实现资源获取
一个摘自Github的示例
class ExampleActivity extends Activity {
@BindView(R.id.user) EditT
@BindView(R.id.pass) EditT
@BindString(R.string.login_error) String loginErrorM
@OnClick(R.id.submit) void submit() {
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.bind(this);
ButterKnife工作原理
以BindView注解使用为例,示例代码为
public class MainActivity extends AppCompatActivity {
@BindView(R.id.myTextView)
TextView myTextV
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
1.程序在compile时,会根据注解自动生成两个类,这里为&MainActivity_ViewBinder.class&和&MainActivity_ViewBinding.class
2.当我们调用&ButterKnife.bind(this);&时,会查找当前类对应的ViewBinder类,并调用bind方法,这里会调用到&MainActiivty_ViewBinder.bind&方法.
3.MainActiivty_ViewBinder.bind方法实际上是调用了findViewById然后在进行类型转换,赋值给MainActivity的myTextView属性
ButterKnife的bind方法
public static Unbinder bind(@NonNull Activity target) {
return getViewBinder(target).bind(Finder.ACTIVITY, target, target);
ButterKnife的&getViewBinder&和&findViewBinderForClass
@NonNull @CheckResult @UiThread
static ViewBinder&Object& getViewBinder(@NonNull Object target) {
Class&?& targetClass = target.getClass();
if (debug) Log.d(TAG, &Looking up view binder for & + targetClass.getName());
return findViewBinderForClass(targetClass);
@NonNull @CheckResult @UiThread
private static ViewBinder&Object& findViewBinderForClass(Class&?& cls) {
ViewBinder&Object& viewBinder = BINDERS.get(cls);
if (viewBinder != null) {
if (debug) Log.d(TAG, &HIT: Cached in view binder map.&);
return viewB
String clsName = cls.getName();
if (clsName.startsWith(&android.&) || clsName.startsWith(&java.&)) {
if (debug) Log.d(TAG, &MISS: Reached framework class. Abandoning search.&);
return NOP_VIEW_BINDER;
Class&?& viewBindingClass = Class.forName(clsName + &_ViewBinder&);
viewBinder = (ViewBinder&Object&) viewBindingClass.newInstance();
if (debug) Log.d(TAG, &HIT: Loaded view binder class.&);
} catch (ClassNotFoundException e) {
if (debug) Log.d(TAG, &Not found. Trying superclass & + cls.getSuperclass().getName());
viewBinder = findViewBinderForClass(cls.getSuperclass());
} catch (InstantiationException e) {
throw new RuntimeException(&Unable to create view binder for & + clsName, e);
} catch (IllegalAccessException e) {
throw new RuntimeException(&Unable to create view binder for & + clsName, e);
BINDERS.put(cls, viewBinder);
return viewB
MainActivity_ViewBinder的反编译源码
androidannotationsample javap -c MainActivity_ViewBinder
Warning: Binary file MainActivity_ViewBinder contains com.example.admin.androidannotationsample.MainActivity_ViewBinder
Compiled from &MainActivity_ViewBinder.java&
public final class com.example.admin.androidannotationsample.MainActivity_ViewBinder implements butterknife.internal.ViewBinder&com.example.admin.androidannotationsample.MainActivity& {
public com.example.admin.androidannotationsample.MainActivity_ViewBinder();
0: aload_0
1: invokespecial #1
public butterknife.Unbinder bind(butterknife.internal.Finder, com.example.admin.androidannotationsample.MainActivity, java.lang.Object);
4: aload_2
5: aload_1
6: aload_3
7: invokespecial #3
10: areturn
public butterknife.Unbinder bind(butterknife.internal.Finder, java.lang.Object, java.lang.Object);
0: aload_0
1: aload_1
2: aload_2
3: checkcast
6: aload_3
7: invokevirtual #5
10: areturn
MainActivity_ViewBinding的反编译源码
androidannotationsample javap -c MainActivity_ViewBinding
Warning: Binary file MainActivity_ViewBinding contains com.example.admin.androidannotationsample.MainActivity_ViewBinding
Compiled from &MainActivity_ViewBinding.java&
public class com.example.admin.androidannotationsample.MainActivity_ViewBinding&T extends com.example.admin.androidannotationsample.MainActivity& implements butterknife.Unbinder {
protected T
public com.example.admin.androidannotationsample.MainActivity_ViewBinding(T, butterknife.internal.Finder, java.lang.Object);
0: aload_0
1: invokespecial #1
4: aload_0
5: aload_1
6: putfield
9: aload_1
10: aload_2
11: aload_3
18: invokevirtual #7
21: checkcast
24: putfield
27: return
public void unbind();
0: aload_0
1: getfield
4: astore_1
5: aload_1
6: ifnonnull
15: invokespecial #11
18: athrow
19: aload_1
20: aconst_null
21: putfield
24: aload_0
25: aconst_null
26: putfield
29: return
Finder的源码
package butterknife.
import android.app.A
import android.app.D
import android.content.C
import android.support.annotation.IdR
import android.view.V
@SuppressWarnings(&UnusedDeclaration&)
public enum Finder {
@Override public View findOptionalView(Object source, @IdRes int id) {
return ((View) source).findViewById(id);
@Override public Context getContext(Object source) {
return ((View) source).getContext();
@Override protected String getResourceEntryName(Object source, @IdRes int id) {
final View view = (View)
if (view.isInEditMode()) {
return &&unavailable while editing&&;
return super.getResourceEntryName(source, id);
ACTIVITY {
@Override public View findOptionalView(Object source, @IdRes int id) {
return ((Activity) source).findViewById(id);
@Override public Context getContext(Object source) {
return (Activity)
@Override public View findOptionalView(Object source, @IdRes int id) {
return ((Dialog) source).findViewById(id);
@Override public Context getContext(Object source) {
return ((Dialog) source).getContext();
public abstract View findOptionalView(Object source, @IdRes int id);
public final &T& T findOptionalViewAsType(Object source, @IdRes int id, String who,
Class&T& cls) {
View view = findOptionalView(source, id);
return castView(view, id, who, cls);
public final View findRequiredView(Object source, @IdRes int id, String who) {
View view = findOptionalView(source, id);
if (view != null) {
String name = getResourceEntryName(source, id);
throw new IllegalStateException(&Required view '&
+ name
+ &' with ID &
+ & for &
+ & was not found. If this view is optional add '@Nullable' (fields) or '@Optional'&
+ & (methods) annotation.&);
public final &T& T findRequiredViewAsType(Object source, @IdRes int id, String who,
Class&T& cls) {
View view = findRequiredView(source, id, who);
return castView(view, id, who, cls);
public final &T& T castView(View view, @IdRes int id, String who, Class&T& cls) {
return cls.cast(view);
} catch (ClassCastException e) {
String name = getResourceEntryName(view, id);
throw new IllegalStateException(&View '&
+ name
+ &' with ID &
+ & for &
+ & was of the wrong type. See cause for more info.&, e);
@SuppressWarnings(&unchecked&)
public final &T& T castParam(Object value, String from, int fromPos, String to, int toPos) {
return (T)
} catch (ClassCastException e) {
throw new IllegalStateException(&Parameter #&
+ (fromPos + 1)
+ & of method '&
+ from
+ &' was of the wrong type for parameter #&
+ (toPos + 1)
+ & of method '&
+ &'. See cause for more info.&, e);
protected String getResourceEntryName(Object source, @IdRes int id) {
return getContext(source).getResources().getResourceEntryName(id);
public abstract Context getContext(Object source);
Otto Bus 是一个专为Android改装的Event Bus,在很多项目中都有应用.由Square开源共享.
public class EventBusTest {
private static final String LOGTAG = &EventBusTest&;
= new Bus();
public void test() {
mBus.register(this);
class NetworkChangedEvent {
public NetworkChangedEvent sendNetworkChangedEvent() {
return new NetworkChangedEvent();
@Subscribe
public void onNetworkChanged(NetworkChangedEvent event) {
Log.i(LOGTAG, &onNetworkChanged event=& + event);
Otto 的工作原理
使用@Produce和@Subscribe标记方法当调用bus.register方法,去检索注册对象的标记方法,并cache映射关系当post事件时,将事件与handler方法对应加入事件队列抽取事件队列,然后调用handler处理
如下为对Otto如何利用注解的分析
register的源码
public void register(Object object) {
if (object == null) {
throw new NullPointerException(&Object to register must not be null.&);
enforcer.enforce(this);
Map&Class&?&, Set&EventHandler&& foundHandlersMap = handlerFinder.findAllSubscribers(object);
for (Class&?& type : foundHandlersMap.keySet()) {
Set&EventHandler& handlers = handlersByType.get(type);
if (handlers == null) {
Set&EventHandler& handlersCreation = new CopyOnWriteArraySet&EventHandler&();
handlers = handlersByType.putIfAbsent(type, handlersCreation);
if (handlers == null) {
handlers = handlersC
final Set&EventHandler& foundHandlers = foundHandlersMap.get(type);
if (!handlers.addAll(foundHandlers)) {
throw new IllegalArgumentException(&Object already registered.&);
for (Map.Entry&Class&?&, Set&EventHandler&& entry : foundHandlersMap.entrySet()) {
Class&?& type = entry.getKey();
EventProducer producer = producersByType.get(type);
if (producer != null && producer.isValid()) {
Set&EventHandler& foundHandlers = entry.getValue();
for (EventHandler foundHandler : foundHandlers) {
if (!producer.isValid()) {
if (foundHandler.isValid()) {
dispatchProducerResultToHandler(foundHandler, producer);
HandlerFinder源码
interface HandlerFinder {
Map&?&, EventProducer& findAllProducers(Object listener);
Map&?&, Set&& findAllSubscribers(Object listener);
//Otto注解查找器
HandlerFinder ANNOTATED = new HandlerFinder() {
public Map&?&, EventProducer& findAllProducers(Object listener) {
return AnnotatedHandlerFinder.findAllProducers(listener);
public Map&?&, Set&& findAllSubscribers(Object listener) {
return AnnotatedHandlerFinder.findAllSubscribers(listener);
具体查找实现
/** This implementation finds all methods marked with a {@link Subscribe} annotation. */
static Map&?&, Set&& findAllSubscribers(Object listener) {
Class&?& listenerClass = listener.getClass();
Map&Class&?&, Set&& handlersInMethod = new HashMap&?&, Set&&();
Map&?&, Set&& methods = SUBSCRIBERS_CACHE.get(listenerClass);
if (null == methods) {
methods = new HashMap&?&, Set&&();
loadAnnotatedSubscriberMethods(listenerClass, methods);
if (!methods.isEmpty()) {
for (Map.Entry&?&, Set&& e : methods.entrySet()) {
Set& handlers = new HashSet&();
for (Method m : e.getValue()) {
handlers.add(new EventHandler(listener, m));
handlersInMethod.put(e.getKey(), handlers);
return handlersInM
以上就是关于Android中注解的一些总结,文章部分内容参考自&&,希望能帮助大家对注解有基础的认识,并运用到实际的日常开发之中.
本文已收录于以下专栏:
相关文章推荐
大家知道,在javaee各技术里面,注解被广泛的使用。那么注解是如何实现的呢?
额。。下面就给出一个本菜鸟 写的一个 仿制 junit测试单元的一个 灰常简单的myTest注解(本人学僧,第一次写博...
前段时间做项目中,业务逻辑要求只要对数据库数据进行改动的都需要记录日志(增删改),记录的内容有操作者,操作的表名及表名称,具体的操作,以及对那条数据进行操作。当时想到的就是Spring 的AOP功能。...
webstorm被称为最智能的JavaScript IDE,不需要为它做过多的介绍。
在开发过程中总是需要对代码进行注解:
//*+回车: /**
* @para...
他的最新文章
讲师:王禹华
讲师:宋宝华
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 nginx 编译自定义目录 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信