昨天听GDG的在线直播讲座, 还是有不少收获的, 今天把这块的知识点总结一下.
首先看一下LayoutInflater.java的inflate()方法.
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) {
return inflate(resource, root, root != null);
}
@LayoutRes和@Nullable就是注解, 起到对参数做到编译期检查的作用. 要求输入的int参数是一个layout资源的id.
正常的调用方式是:
mRenameDialog.getLayoutInflater().inflate(R.layout.create_directory, null);
如果我们输入一个R.color.black,
mRenameDialog.getLayoutInflater().inflate(R.color.black, null);
虽然也是一个int值,但不是layout资源的id, android studio会给出一个提示性的错误(expected resource of type layout), 但并不会导致编译不通过.
但在运行时, 会crash.
08-08 11:07:27.545 15711-15711/com.qihoo.browser E/AndroidRuntime﹕ FATAL EXCEPTION: main
android.content.res.Resources$NotFoundException: Resource ID #0x7f110011 type #0x1d is not valid
at android.content.res.Resources.loadXmlResourceParser(Resources.java:2171)
at android.content.res.Resources.getLayout(Resources.java:859)
at android.view.LayoutInflater.inflate(LayoutInflater.java:394)
at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
at com.qihoo.browser.activity.SaveWebPagesActivity$4.onPopItemSelected(SaveWebPagesActivity.java:272)
at com.qihoo.browser.dialog.CustomPopupDialog.onClick(CustomPopupDialog.java:270)
at android.view.View.performClick(View.java:4278)
at android.view.View$PerformClick.run(View.java:17430)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:5092)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:564)
at dalvik.system.NativeStart.main(Native Method)
上面这个例子就是注解的一个典型的应用, 实际上起到的是一个编译期, 代码检查的作用.
对于更优雅地写一个基础类给上层代码调用, 是一个很好的编码规范.
类似的还有, 如果你写一个API, 希望调用者对返回结果进行检查,
就可以使用注解@CheckResult
@CheckResult(suggest="#enforceCallingOrSelfPermission(String,String)")
public abstract int checkCallingOrSelfPermission(@NonNull String permission);
这样, 如果调用者没有把返回值赋值给自己的变量的话,
尽管编译可以通过, 但android studio会给出错误提示.
我之前总结的Hugo打印log的库也是通过@DebugLog注解的方式实现的.
下面是讲座的slide.
===DONE===