EP19-ButterKnife会影响APP运行效率吗?

0x00 要不要使用

ButterKnife是一个「依赖注入(dependency injection)」的工具。使用它的话,可以使用注解来绑定view、资源或者onclicklistener,省去了findViewById的操作。像这样:

@BindView(R.id.user) EditText username;
  @BindView(R.id.pass) EditText password;

  @BindString(R.string.login_error) String loginErrorMessage;

  @OnClick(R.id.submit) void submit() {
    // TODO call server...
  }

这边提一下「依赖注入」这个概念,我理解的就是在运行时给类注入一些参数,比如构造方法传入参数。这叫做「构造方法注入」,可以实现解耦。

类似的工具还是Dagger、RoboGuice等等,我们看到很多人会担心依赖注入的工具会影响性能,比如有的人提到:

使用RoboGuice之后,代码是简化了不少;然而,注入框架会扫描你的代码执行很多初始化的操作,会导致你的代码需要大量内存空间来mapping代码,而且mapped pages会长时间被保留在内存中。除非很有必要,谨慎使用这种技术。

对于内存管理,Google在Manage Your App's Memory点名批评了Guice和RoboGuice(现在已经去掉了..),然后安利了Dagger 2,因为:

If you intend to use a dependency injection framework in your app, consider using Dagger 2. Dagger does not use reflection to scan your app's code. Dagger's static, compile-time implementation means that it can be used in Android apps without needless runtime cost or memory usage.
如果你想要使用依赖注入框架,考虑使用Dagger 2,Dagger不会使用反射来扫描你app的代码。Dagger的静态、编译时实现意味着它不会产生额外的runtime cost或者内存使用。

Other dependency injection frameworks that use reflection tend to initialize processes by scanning your code for annotations. This process can require significantly more CPU cycles and RAM, and can cause a noticeable lag when the app launches.
其他使用反射的依赖注入框架倾向于通过扫描你代码里的注解来初始化进程。需要显著的CPU和RAM资源。

0x01 ButterKnife的原理

使用注解处理器。Java编译器编译代码之前会先调用注解处理器,所以可以继承AbstractProcessor,自己写注解处理器。这样就可以在编译代码之前执行一段我们自己的代码了。比如生成新的代码,或者检查注解的代码是否规范。在ButterKnifeProcessor.process里:

  1. 扫描所有的注解
  2. 自动生成一个ViewBinder类,包含findViewByIdsetOnClickListener等等
  3. 加载生成的ViewBinder,调用其中的bind方法
// Process each @Bind element.
 for (Element element : env.getElementsAnnotatedWith(Bind.class)) {
   if (!SuperficialValidation.validateElement(element)) continue;
   try {
     parseBind(element, targetClassMap, erasedTargetNames);
   } catch (Exception e) {
     logParsingError(element, Bind.class, e);
   }
 }

这个跟笑哥的hotfix不同,hotfix是在运行时在补丁apk(dex)里搜寻fixed注解然后生成新的类,替换原来的dex。这个过几天可以分析一波。
嗯,结论就是,ButterKnife是不影响App性能的,可以放心食用。

具体的话,可以参考:
[1]http://bxbxbai.github.io/2016/03/12/how-butterknife-works/?utm_source=tuicool&utm_medium=referral
[2]https://zhuanlan.zhihu.com/p/21628698

你可能感兴趣的:(EP19-ButterKnife会影响APP运行效率吗?)