珍惜生命 远离 Butter Knife
2016-05-16 23:04
483 查看
Butter Knife 是什么呢?
Bind Android views and callbacks to fields and methods.http://jakewharton.github.io/butterknife/没错,Butter Knife 就是 大名鼎鼎的 Android 大神 Jake Wharton 开源的View 注入框架 ,在过去的两年里,赢得了近万人的点赞,近两千人建立了代码分支。配合着Android Studiobutterknife-zelezny
插件的使用极大的提高了Android 项目的开发效率,先让我们看一看 butterknife-zelezny 的辉煌表现吧
仅仅几秒钟的时间,就可以将布局 中所有声明了ID的控件全部生成变量并绑定到相应的View 上。 虽然注解的方式也受性能的诟病,但是相比起 findViewByid的痛苦及开发效率的提升这简直不值一提,相信不少程序员为了妥协无知产品经理定下的工期(没错是产品定下的工期)而选择了 Butter Knife,当然,我相信也有一些朋友是为了所谓的代码的优雅。
无论怎样,做为时代的产物,Butter Knife 已经深深嵌进了成千上万个Android应用项目中。
在我开发的项目中,同样也使用了这个东西,当然,我使用Butter Knife的初衷不是因为 代码的优雅,而是为了应付瞬息万变的产品需求与落后的开发速度之间的矛盾。
直到有一天,突然有这样一个需求:把整个项目打包成SDK。
打包成SDK给自己用本来是没有什么的,无非就是 把 build.gradle 的插件换一下而已。
apply plugin: 'com.android.library' //apply plugin: 'com.android.application'
然而,如果这个SDK 是给别人用的,那么问题就来了,把一个55K的 Butter Knife jar 包 放到 这里面,仅仅是为了替代findViewById,这不管怎么说都会让人觉得有些奇怪。
事实证明,我要立刻减少对Butter Knife 的依赖,好在已经有善良的朋友为万能的AndroidStudio 开发了一套新的插件
https://github.com/boredream/BorePlugin 到目前为止,我也没有明白这位仁兄为什么把这个项目叫 BorePlugin 不过这并不影响我们使用。让我们见识一下真正的生产力工具吧。
可是,以前的项目怎么办呢?想想一个一个的去改都头大了!但是,做为一个优秀的工程师,决不能忍受这样的痛苦,为此,有朋友为我们准备好了修改项目的 python 脚本 。配置好你的python 环境。把这个脚本放到项目目录下,运行脚本,很快
@BindView标签 全变成了 标准的 findViewByid
# -*- coding: utf-8 -*- import os import re # CLASS_NAME_PATTERN = re.compile('') BUTTER_KNIFE_PATTERN = re.compile('(ButterKnife.bind\(.*?,*\s*(.*)\);)') BIND_PATTERN = re.compile('(@Bind\((.*?)\)\s*(.*?)\s+(.*?);)') CLICK_PATTERN = re.compile('(@OnClick\(\s*\{?(.*?)\}\s*\))') FIND_VIEW_FORMAT_WITH_VIEW = ' %s = (%s) %sfindViewById(%s);\n' # FIND_VIEW_FORMAT = ' %s = (%s) findViewById(%s);\n' SET_CLICK_FORMAT = ' %s.setOnClickListener(this);\n' SET_CLICK_FORMAT_BY_FIND_VIEW = ' %sfindViewById(%s).setOnClickListener(this);\n' def insert_find_view_method(source, add): pos = source.rfind('}') changed = source[:pos] + add if pos + 1 < len(source): # not last changed += source[pos + 1:] return changed def get_click_str(binds, click_id, view): for i in binds: if click_id == i[1].replace(' ', ''): return str.format(SET_CLICK_FORMAT % (i[3])) return str.format(SET_CLICK_FORMAT_BY_FIND_VIEW % (view, click_id)) def replace_butter_knife(java_path): with open(java_path) as java_file: content = java_file.read() butters = BUTTER_KNIFE_PATTERN.findall(content) m_view = "" if butters: butter = butters[0] # print butter content = content.replace(butter[0], "initView();") if butter[0].find(',') != -1 and butter[1]: m_view = butter[1].split(',')[1].replace(" ", "") + '.' binds = BIND_PATTERN.findall(content) init_method = '\n private void initView() {\n' for bind in binds: view_id = bind[1] view_type = bind[2] view_filed = bind[3] content = content.replace(bind[0], 'private'+" "+view_type + " " + view_filed + ";") # if m_view: init_method += str.format(FIND_VIEW_FORMAT_WITH_VIEW % (view_filed, view_type, m_view, view_id)) # else: # init_method += str.format(FIND_VIEW_FORMAT % (view_filed, view_type, view_id)) onclick = CLICK_PATTERN.findall(content) if onclick: content = content.replace(onclick[0][0], '@Override') click_ids = onclick[0][1].replace(' ', '').split(',') for click_id in click_ids: # print click_id init_method += get_click_str(binds, click_id, m_view) init_method += " }\n}" content = insert_find_view_method(content, init_method) java_file.close() new = open(java_path, "wb") new.write(content) new.close() print os.path.split(java_path)[1] + " DONE" # print content if __name__ == '__main__': current_path = os.getcwd() input_path = '' input_path = raw_input(r'press enter to start replace butter knife') if input_path == '': for root, dirs, files in os.walk(current_path): for f in files: if os.path.splitext(f)[1] == '.java': replace_butter_knife(os.path.join(root, f))
脚本下载地址 http://download.csdn.net/download/github_14899071/9522171
相关文章推荐
- jQuery获取h1-h6元素的值
- bootstrap table 插件 搜索
- 前端资源教程合集
- jQuery学习日记---第三篇 JS实现导航条点击以后会高亮显示
- SharedPrefercences存储
- 剑指offer02--入栈和出栈
- JSP基本介绍
- jQuery-制作黑白反斗棋页面
- HTML中img标签及相关属性
- 279. Perfect Squares
- iScroll.js 使用方法参考
- 如何创建第一个React Native android应用
- AjaxAnywhere(jsp局部刷新、ajax刷新)
- javascript:js脚本的3中引入方法
- MySQL:Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEM
- javascript基础-黑白反斗棋
- EL表达式/JSP标签和EL表达式
- Codeforces Round #352 (Div. 2)-B. Different is Good(模拟)
- nodejs的一些核心概念
- JavaScript的无阻塞加载