该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2011-03-26
lmxbitihero 写道 cloixio 写道 看到javaeye很多人在吹嘘、推荐杨丰盛的《Android应用开发揭秘》,个人就买了一本。
首先拿到书时,再次感受到机工出版社的书的纸张独有的“薄如蝉翼、黄如粪便”的特征,不过想着javaeye一众人对书中内容的推荐,纸张的质量我忍了。 接着看书,不过我慢慢发现书中一堆晦涩不清的表述——这种表述可能是我自己的中文理解问题,算了不说了。 但书中还充斥着一堆垃圾代码,看下面书中代码(P270,免得说我诬陷): private Runnable _discoveryWorkder = new Runnable() { public void run() { /* 开始搜索 */ _bluetooth.startDiscovery(); for (;;) { if (_discoveryFinished) { break; } try { Thread.sleep(100); } catch (InterruptedException e){} } } }; 上面_bluetooth.startDiscovery();就是开始进行蓝牙搜索了, 接下来那段死循环就纯属多余!!代码判断_discoveryFinished为true时结束死循环,但这个死循环什么都没做啊。 事实上,完全可以把这段垃圾代码删除。 我不确定杨丰盛到底会不会Android,但我觉得这java代码写得也太垃圾了。 书中大量这种的代码,让人不堪入目。前几章,看过也就算了,后来发现越来越多 上来发发牢骚。 _discoveryFinished这个变量在其他地方被改变,那个死循环当然是有用的。 请注意,我并不是说这个死循环不会退出,这点简单的内容就不需要你拿出来说了。 当_discoveryFinished为false时,该循环会退出,谁都知道。 我的问题是:这个死循环的有意义吗? 既然你还不懂,我就跟你解释一下: 这个程序定义了一个线程来执行蓝牙搜索,这条线程只做了2件事情: 1. _bluetooth.startDiscovery(); ——这条代码是个耗时操作。 2. 死循环。 第一种假设:假如_bluetooth.startDiscovery(); 是同步执行的,等这条代码执行完成后,再去执行死循环,那死循环有意义吗? 幸好Android没有这么SB!这里是异步执行的——也就是说死循环与_bluetooth.startDiscovery();并发执行,当死循环 执行Thread.sleep(100)时,系统完全可能去执行 _bluetooth.startDiscovery();这个耗时操作,那死循环有意义吗? |
|
返回顶楼 | |
发表时间:2011-03-26
yarin 写道 只能说明这位仁兄喜欢自己的设备的CPU使用率永远都是100%的。
最大限度的发挥设备的能力。 帮助用户消耗一部分电量。 非常抱歉,本书没有满足你上诉要求! 既然作者用这么NB哄哄的口吻来解释, 我就再发表一下我的看法: 看来作者认为这个死循环是可以让_bluetooth.startDiscovery();这个耗时操作暂停下来,让CPU空闲出来。 看来有必要补充一下多线程的知识了: 这个程序定义了一个线程来执行蓝牙搜索,这条线程只做了2件事情: 1. _bluetooth.startDiscovery(); ——这条代码是个耗时操作。 2. 死循环。 第一种假设:假如_bluetooth.startDiscovery(); 是同步执行的,也就是程序必须等这条代码执行完成后,才会去执行死循环,那死循环能暂停_bluetooth.startDiscovery();这个耗时操作吗?能让CPU空闲出来吗? 幸好Android没有这么SB!因为这个操作完全可能会搜索1~3分钟。这里是异步执行的——也就是说死循环与_bluetooth.startDiscovery();其实是并发执行的。那么根据多线程的“基础知识”:当死循环线程 执行Thread.sleep(100)时,系统完全可能会被调度到去执行 _bluetooth.startDiscovery();这个耗时操作,那么死循环有意义吗? |
|
返回顶楼 | |
发表时间:2011-03-26
cloixio 写道 yarin 写道 只能说明这位仁兄喜欢自己的设备的CPU使用率永远都是100%的。
最大限度的发挥设备的能力。 帮助用户消耗一部分电量。 非常抱歉,本书没有满足你上诉要求! 既然作者用这么NB哄哄的口吻来解释, 我就再发表一下我的看法: 看来作者认为这个死循环是可以让_bluetooth.startDiscovery();这个耗时操作暂停下来,让CPU空闲出来。 看来有必要补充一下多线程的知识了: 这个程序定义了一个线程来执行蓝牙搜索,这条线程只做了2件事情: 1. _bluetooth.startDiscovery(); ——这条代码是个耗时操作。 2. 死循环。 第一种假设:假如_bluetooth.startDiscovery(); 是同步执行的,也就是程序必须等这条代码执行完成后,才会去执行死循环,那死循环能暂停_bluetooth.startDiscovery();这个耗时操作吗?能让CPU空闲出来吗? 幸好Android没有这么SB!因为这个操作完全可能会搜索1~3分钟。这里是异步执行的——也就是说死循环与_bluetooth.startDiscovery();其实是并发执行的。那么根据多线程的“基础知识”:当死循环线程 执行Thread.sleep(100)时,系统完全可能会被调度到去执行 _bluetooth.startDiscovery();这个耗时操作,那么死循环有意义吗? 虽然我承认国内的书不怎么样,但这里还是要说你这种说法是不对的。 这里书的作者的做法类似于spinlock,如果你bluetooth在搜索完成后没有回调的话,那死循环检查标志位是必然的做法。这在系统内核或者串口通讯是很常见的做法 |
|
返回顶楼 | |
发表时间:2011-03-26
nianien 写道 qq.jiang 写道 咖啡豆子 写道 如果这个_bluetooth.startDiscovery()是异步的,代码也没什么问题,只是编码风格不太好
同感,没写过android开发,查一下文档即可。 不过http://developer.android.com/打不开,这个~~ 上述代码就是有问题,如果_bluetooth.startDiscovery()是异步的,这边却无限循环去等待异步完成,那么异步就是多余的,如果是同步的话,那么后面的循环代码就是多余的. 无论有没有上下文,这段代码都是有问题的,力挺LZ~~~~~~~ 这只是一个告诉你怎么检测bluetooth完成的一个样例,作者是假定有部分读者可能JAVA经验不多才这样写,要是只写给熟练的JAVA开发者的话,这里只要说一句startBluetooth是异步的,标志位是什么就OK了。 |
|
返回顶楼 | |
发表时间:2011-03-26
咖啡豆子 写道 nianien 写道 qq.jiang 写道 咖啡豆子 写道 如果这个_bluetooth.startDiscovery()是异步的,代码也没什么问题,只是编码风格不太好
同感,没写过android开发,查一下文档即可。 不过http://developer.android.com/打不开,这个~~ 上述代码就是有问题,如果_bluetooth.startDiscovery()是异步的,这边却无限循环去等待异步完成,那么异步就是多余的,如果是同步的话,那么后面的循环代码就是多余的. 无论有没有上下文,这段代码都是有问题的,力挺LZ~~~~~~~ 这只是一个告诉你怎么检测bluetooth完成的一个样例,作者是假定有部分读者可能JAVA经验不多才这样写,要是只写给熟练的JAVA开发者的话,这里只要说一句startBluetooth是异步的,标志位是什么就OK了。 但是这样不是更误导读者么?还真会给作者开脱~ |
|
返回顶楼 | |
发表时间:2011-03-26
哥手头正有一本,还没看过呢。。楼主,我是不是改扔掉?
|
|
返回顶楼 | |
发表时间:2011-03-26
nianien 写道 咖啡豆子 写道 nianien 写道 qq.jiang 写道 咖啡豆子 写道 如果这个_bluetooth.startDiscovery()是异步的,代码也没什么问题,只是编码风格不太好
同感,没写过android开发,查一下文档即可。 不过http://developer.android.com/打不开,这个~~ 上述代码就是有问题,如果_bluetooth.startDiscovery()是异步的,这边却无限循环去等待异步完成,那么异步就是多余的,如果是同步的话,那么后面的循环代码就是多余的. 无论有没有上下文,这段代码都是有问题的,力挺LZ~~~~~~~ 这只是一个告诉你怎么检测bluetooth完成的一个样例,作者是假定有部分读者可能JAVA经验不多才这样写,要是只写给熟练的JAVA开发者的话,这里只要说一句startBluetooth是异步的,标志位是什么就OK了。 但是这样不是更误导读者么?还真会给作者开脱~ 这不是开脱的问题,事实上我也几乎不买国内作者的书,但就书上这一处来说是LZ自己没有理解,就事论事而已 |
|
返回顶楼 | |
发表时间:2011-03-26
if(RB == SB){
//Everyon understand... } |
|
返回顶楼 | |
发表时间:2011-03-26
sniffer123 写道 cloixio 写道 yarin 写道 只能说明这位仁兄喜欢自己的设备的CPU使用率永远都是100%的。
最大限度的发挥设备的能力。 帮助用户消耗一部分电量。 非常抱歉,本书没有满足你上诉要求! 既然作者用这么NB哄哄的口吻来解释, 我就再发表一下我的看法: 看来作者认为这个死循环是可以让_bluetooth.startDiscovery();这个耗时操作暂停下来,让CPU空闲出来。 看来有必要补充一下多线程的知识了: 这个程序定义了一个线程来执行蓝牙搜索,这条线程只做了2件事情: 1. _bluetooth.startDiscovery(); ——这条代码是个耗时操作。 2. 死循环。 第一种假设:假如_bluetooth.startDiscovery(); 是同步执行的,也就是程序必须等这条代码执行完成后,才会去执行死循环,那死循环能暂停_bluetooth.startDiscovery();这个耗时操作吗?能让CPU空闲出来吗? 幸好Android没有这么SB!因为这个操作完全可能会搜索1~3分钟。这里是异步执行的——也就是说死循环与_bluetooth.startDiscovery();其实是并发执行的。那么根据多线程的“基础知识”:当死循环线程 执行Thread.sleep(100)时,系统完全可能会被调度到去执行 _bluetooth.startDiscovery();这个耗时操作,那么死循环有意义吗? 虽然我承认国内的书不怎么样,但这里还是要说你这种说法是不对的。 这里书的作者的做法类似于spinlock,如果你bluetooth在搜索完成后没有回调的话,那死循环检查标志位是必然的做法。这在系统内核或者串口通讯是很常见的做法 假设并不是为作者开脱吧,你所说的标志位_discoveryFinished 其实也是多余的,它的作用就是控制死循环的退出。 这段程序我真没有贴完,你所说的回调,这个程序完全是有的。程序分别使用了两个BroadcastReceiver来处理搜到蓝牙设备、搜索完成后的的回调,程序代码如下: /** * 接收器 * 当搜索蓝牙设备完成时调用 */ private BroadcastReceiver _foundReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { /* 从intent中取得搜索结果数据 */ BluetoothDevice device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); /* 将结果添加到列表中 */ _devices.add(device); /* 显示列表 */ showDevices(); } }; private BroadcastReceiver _discoveryReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { /* 卸载注册的接收器 */ unregisterReceiver(_foundReceiver); unregisterReceiver(this); _discoveryFinished = true; } }; 希望你知道Android中BroadcastReceiver是干什么的。 |
|
返回顶楼 | |
发表时间:2011-03-26
tiantianfei 写道 哥手头正有一本,还没看过呢。。楼主,我是不是改扔掉?
这个我就不知道了。 当初我也是看到javaeye上的很多人在吹嘘这本书才去买的,现在后悔到死。 几乎全新,如有人愿意接受,5折转让(包邮),如果不包邮,可以4折转让。 ——不想每天案头看到这本书就生气。 |
|
返回顶楼 | |