这份工作为什么不让我开心
我想要优化每一个图片的大小,精准地选择文件格式和参数。
我想要每一个像素都对齐,每一个按钮都有合适的 ripple 效果。
但是整个公司根本没有一个人在乎。
所有人只在乎功能更快做完上线。
我想要优化每一个图片的大小,精准地选择文件格式和参数。
我想要每一个像素都对齐,每一个按钮都有合适的 ripple 效果。
但是整个公司根本没有一个人在乎。
所有人只在乎功能更快做完上线。
Android 开发中,用得最常见的 interface 之一便是 OnClickListener 了。不使用 android:onClick 属性的话,自然就不得不去 implement OnClickListener。
假设我们不使用任何框架或是架构模式,只是写一个简单的 Activity;在一个 Activity 中有多个可点击的按钮时,我的同事会这么写:
public class ExampleActivity extends Activity implements OnClickListener {
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_example);
findViewById(R.id.first_button).setOnClickListener(this);
findViewById(R.id.second_button).setOnClickListener(this);
}
@Override
public void onClick(final View v) {
switch (v.getId()) {
case R.id.first_button:
// bla bla bla
break;
case R.id.second_button:
// bra bra bra
}
}
}
事实上,Android 官方有些 sample 里面也是这么写的。然而在我看来,这么写代码是非常不优雅的,因为一个 OnClickListener 的实现,只应该关注和点击事件本身相关的内容,它的含义和 Activity 的含义是截然无关的,让同一个类继承/实现他们,会使得这个类的含义变得不清晰。同时,这样还给 ExampleActivity 类增加了一个 public 的方法,削弱了这个类的封闭性。
所以如果像下面这样,会好不少:
public class ExampleActivity extends Activity {
private OnClickListener onClickListener = new OnClickListener() {
@Override
public void onClick(final View v) {
switch (v.getId()) {
case R.id.first_button:
// bla bla bla
break;
case R.id.second_button:
// bra bra bra
}
}
};
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_example);
findViewById(R.id.first_button).setOnClickListener(onClickListener);
findViewById(R.id.second_button).setOnClickListener(onClickListener);
}
}
这样写体现了 composition over inheritance 的思想。它避免了上面的所有问题,看起来舒服得多。
不过,这样还是让阅读代码时很不方便——看到 onCreate 里面时,还不得不经常滚动到声明 onClickListener 的地方去,并且在 onClick 中艰难地寻找真正和某个特定按钮相关的代码。当然这两个问题之前那个版本也都无法避免。
另一件糟糕的事情是,不同按钮的 listener 逻辑很可能是相对独立的,放到同一个 onClickListener 里,还是很丑陋。
所以为了进一步避免这几个问题,我一向都是用下面这样的写法:
public class ExampleActivity extends Activity {
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_example);
findViewById(R.id.first_button).setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View v) {
// bla bla bla
}
});
findViewById(R.id.second_button).setOnClickListener(new OnClickListener() {
@Override
public void onClick(final View v) {
// bra bra bra
}
});
}
}
这样的话,不同逻辑间相对独立,看起来非常舒服,便于阅读,并且让我找回了写 JavaScript 的舒畅感觉(划掉)。
那么问题来了:为什么有的人不使用最后一种写法呢?
Recently, I made a decision to disallow programmers to use android:onClick XML attributes to add click event listeners. Existing usages will be removed too. Actually, the attribute itself was a very bad design, considering that web frontend developers has switched from onclick HTML attribute to addEventListener API for a long time.
Here are the real reasons why android:onClick XML attribute should be avoided:
android:onClick no longer works, because the program will look for the click handler from ContextThemeWrapper instead of Activity (see http://stackoverflow.com/questions/29525644/). When applying a theme, programmers may not realize the problem.Activity. When programmers change an Activity into a Fragment, they may be ignoring this problem.onClick uses reflection. It therefore prevents the compiler from telling you problems. You app will crash at run time.android:onClick attribute, but no android:onChange or any other XML attributes for event listeners. Considering click listeners aren't really different from other event listeners, keeping them consistent will be good.android:onClick, one must create a public method with parameter (View view). Android Lint will then complain "unused parameter".有时候我也在想,为什么我以前无法做到在 Linux 下工作,而现在却能做到。
正好那天和别人谈起,我干脆就列出我用过的所有 Linux 发行版好了。
按道理讲这个不算,因为就装上去用了几天而已。实在不会安装软件。当时主流的软件分发方式还是丢一个 tar 包让你自己编译,于是当时安装 Real Player 都用了很久——而根本没有其它好用的播放器。
作为双系统的第二系统。那时候有一台 Athlon 64 2800 处理器的电脑。
基本都是作为双系统的第二系统,或是一台老旧的笔记本的唯一系统。那天老旧的笔记本常被我用来写东西和看毛片。
大学里前后换了三台笔记本。系统也一直在换来换去。Arch 和 SUSE 都很可爱,但是用起来实在不省心。而且 zypper 和 pacman 真的很难用(比起 apt-get 和 yum 来说)。
毕业以后基本没时间折腾了,Xfce 简单、稳定,并且在那台老旧的笔记本上也能舒畅的运行。后来公司发了台好笔记本,于是打算换炫一点的 GNOME Shell。而之前的经历告诉我,网上太多 binary 包都只有 deb 版,于是装 Debian 系的系统是最好的选择。一开始试了试 Ubuntu GNOME,发现中文输入法一直有问题。于是就换了 Debian unstable,很是舒畅。
善良的少年啊
当你决定去屠龙的那一刻
我就明白 你终将会成为下一只恶龙
但我还是为你的勇气倾心
让我站着人群中 默默敬你这一杯酒
和我心上的少年 诀别