珍惜生命 远离 Butter Knife

 

  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 的辉煌表现吧


珍惜生命 远离 Butter Knife_第1张图片


     仅仅几秒钟的时间,就可以将布局 中所有声明了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  不过这并不影响我们使用。让我们见识一下真正的生产力工具吧。

珍惜生命 远离 Butter Knife_第2张图片


珍惜生命 远离 Butter Knife_第3张图片



珍惜生命 远离 Butter Knife_第4张图片




      可是,以前的项目怎么办呢?想想一个一个的去改都头大了!但是,做为一个优秀的工程师,决不能忍受这样的痛苦,为此,有朋友为我们准备好了修改项目的 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


            然而,这对于不了解 python  的朋友无疑是一场灾难!安装python 环境,还要学着运行python 命令,想想就够了。
          时间总是能带给人们意想不到的惊喜,就在几天前,没错,几天前,有大神开源了一款AndroidStudio 插件神器,现在,你不再需要python 基础,不需要python 环境,也不需要python 脚本。你只要会安装AndroidStudio 插件就可以  RemoveButterKnife,从此和 Butter Knife 说再见 了!

         让我们见识一下吧!

    珍惜生命 远离 Butter Knife_第5张图片



       更重要的是 

    

    没错,作者看起来像个中国人 

    深受Butter Knife之害的朋友,快来体验一下     https://github.com/u3shadow/RemoveButterKnife 吧。









你可能感兴趣的:(Android,github)