<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    amp@java

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      99 隨筆 :: 0 文章 :: 228 評論 :: 0 Trackbacks

    2007年7月9日 #

    當(dāng)年是從CSDN博客遷過來的,因?yàn)槟抢锖懿环€(wěn)定,那時候這里很火的;
    前段時間發(fā)現(xiàn),Blogjava的登錄頁面居然沒有驗(yàn)證碼了,圖片顯示錯誤,無法登錄,預(yù)感這個地方要涼,只好到處找替代,但沒找到好用的博客,github是一個選項(xiàng),但似乎不是很適合做博客。
    現(xiàn)在終于又可以登錄了,不過首頁居然只剩一篇文章,我以為數(shù)據(jù)都沒了,登錄發(fā)現(xiàn)還是有的,不過太讓人不放心了。
    posted @ 2018-08-18 22:14 amp@java 閱讀(149) | 評論 (0)編輯 收藏

     昨天下午開始,之前用得好好的USB鼠標(biāo),突然不能用了,找到個PS/2鼠標(biāo),卻發(fā)現(xiàn)主板沒有鼠標(biāo)的PS/2口,只有鍵盤的PS/2口,真是奇葩,幸好在用的鍵盤是PS/2口的,費(fèi)了九牛二虎之力,用鍵盤操作,Win+R,compmgmt.msc進(jìn)入計算機(jī)管理,上下箭頭移到設(shè)備管理器,發(fā)現(xiàn)右邊的USB控制器前全是黃色嘆號,嘗試卸載再安裝,卻怎么也裝不上,重新啟動發(fā)現(xiàn)鼠標(biāo)在啟動Windows前還是亮燈的,但到了顯示W(wǎng)indows徽標(biāo)的時候燈就滅了,應(yīng)該不是硬件問題,而是驅(qū)動問題。
    為了進(jìn)一步證實(shí)硬件沒問題,找了個安裝系統(tǒng)的U盤,插進(jìn)去啟動,能夠正常使用鼠標(biāo),于是目標(biāo)就聚焦在找回驅(qū)動上。
    開始折騰:
    1、首先是找官方驅(qū)動啊,我這電腦是老機(jī),AMD7系列主板,找了半天,這個主板驅(qū)動并沒有包含USB控制器,因?yàn)閁SB控制器都是Windows自帶的驅(qū)動,下載了一個南橋驅(qū)動,安裝后并沒有效果;
    2、Windows自帶的驅(qū)動原來都是放在C:\Windows\System32\DriverStore\FileRepository下,USB控制器相關(guān)的驅(qū)動,就在usbport.inf_amd64_xxxxxxxxxx文件夾里,xxxxxxxxx是一串16進(jìn)制數(shù)字,悲催的是,安裝這個驅(qū)動時要不提示找不到指定文件,要不說第三方INF沒有簽名;
    3、自己折騰搞不定,找個軟件吧,第一個想到的是驅(qū)動之家官方的驅(qū)動精靈,下載下來發(fā)現(xiàn)是個全家桶啊,什么騰訊管家,金山毒霸,瀏覽器首頁修改一應(yīng)俱全,而且沒有鼠標(biāo)點(diǎn)擊,用TAB鍵根本移動不到取消框,只好默認(rèn)全部安裝了,裝完啟動,檢測,提示系統(tǒng)自帶驅(qū)動缺失,于是回車修復(fù),但每次修復(fù)完,重新檢測還是那樣,而且沒有提示USB控制器驅(qū)動安裝有問題,有些功能用鍵盤無法操作,不知道是不是還有哪里可以操作一下,于是又搜了一下,如何用鍵盤代替鼠標(biāo),居然真的找到了!
    4、按WIN鍵,輸入設(shè)置,回車,打開設(shè)置主頁:

    移到“輕松使用”,進(jìn)去后左邊選擇“鼠標(biāo)”,在右邊啟用“使用數(shù)字小鍵盤在屏幕上移動鼠標(biāo)”(按空格鍵開關(guān)),最好把三個開關(guān)都打開,如果沒有啟用CTRL鍵加速功能,鼠標(biāo)移動非常慢:

    好了,現(xiàn)在可以用小鍵盤移動鼠標(biāo)了;
    5、繼續(xù)回到驅(qū)動精靈,再次修復(fù),還是不行啊,這個東西除了帶來一堆垃圾,什么作用都沒有!于是把它帶來的垃圾以及它自己卸載了。
    6、似乎360也有一個驅(qū)動大師,于是就下載了一個,這個倒是很純潔,但是功能太弱,完全沒發(fā)現(xiàn)問題;
    7、剛才搜索“安裝驅(qū)動 找不到指定的文件”時,發(fā)現(xiàn)一個論壇提到了這個,是驅(qū)動人生的論壇,好像還有解決方案,但要注冊才能下載,難道驅(qū)動人生可以解決?于是就下載了一個驅(qū)動人生,安裝的時候還是附帶全家桶,不過現(xiàn)在可以用鍵盤移動鼠標(biāo)取消了,只安裝了驅(qū)動人生自己,跟剛才兩個軟件不同的是,它提示USB外設(shè)驅(qū)動沒有安裝,于是點(diǎn)修復(fù),結(jié)果反反復(fù)復(fù)出現(xiàn)等待光標(biāo),就是無法完成;
    8、之前又搜索到,驅(qū)動安裝的日志在C:\Windows\INF\setupapi.dev.log文件里,于是打開這個文件,發(fā)現(xiàn)Driver package failed signature verification. Error = 0xE000022F,驅(qū)動程序簽名有問題,所以不能安裝成功;
    9、Windows10有個高級啟動選項(xiàng)是禁用強(qiáng)制驅(qū)動簽名,如何進(jìn)入高級啟動選項(xiàng)呢?以前是按F8,現(xiàn)在不行了,要在設(shè)置里面,更新和安全,恢復(fù),高級啟動,立即重啟,然后設(shè)置疑難解答,高級啟動,再重啟,就可以進(jìn)入高級啟動菜單,按7進(jìn)入禁止強(qiáng)制驅(qū)動簽名模式,重啟后再用驅(qū)動人生修復(fù),果然成功了;
    10、打開驅(qū)動人生下載目錄,DTLFolder\DriversDownLoad,發(fā)現(xiàn)它下載了USB驅(qū)動目錄是USB_10.0.10240.16384_WHQL_107049,里面文件如下:

    除了第一個xml文件是程序自己用的外,其他都是USB驅(qū)動用到的文件,點(diǎn)右鍵發(fā)現(xiàn)那幾個sys文件,除了usbohci.sys和usbuhci.sys外,其他都有數(shù)字簽名,而usbuhci.sys我這里沒用到,問題就出在usbohci.sys上:


    11、難道是驅(qū)動人生替換了未簽名的文件?圖謀不軌?為了驗(yàn)證一下,我又下載了一個Windows10安裝光盤(版本是當(dāng)前使用的1703版):
    cn_windows_10_multiple_editions_version_1703_updated_march_2017_x64_dvd_10194190.iso
    12、怎么提取安裝光盤中的內(nèi)置驅(qū)動?找了一下,原來Windows的安裝盤從VISTA起,不再使用XP以前的I386目錄和Drivers.cab文件存放驅(qū)動,而是打包在一個Install.wim鏡像文件中,要找到驅(qū)動文件,必須用工具提取,這個工具就是Imagex.exe,微軟自己做的命令行工具,但是我的電腦上沒有,于是下載了一個64位的,放在C盤根目錄,通過如下命令即可提取:
    c:\IMAGEX_x64 /mount f:\sources\install.wim 5 i:\1703
    其中F盤是在iso文件上點(diǎn)右鍵,打開方式選“Windows資源管理器”打開后虛擬出來的盤符,其實(shí)就相當(dāng)于系統(tǒng)自帶的虛擬光驅(qū),I盤是硬盤,用來存放掛載的鏡像文件,5是選擇掛載哪一個版本的Windows(多合一版),如果不知道要掛哪個,把這個數(shù)字改成100,會顯示xml文件內(nèi)容,并提示找不到這個索引號,從xml文件內(nèi)容就能找到各版本的信息,然后再重新掛載正確的即可。這個掛載其實(shí)是個解壓縮過程,時間很長,提取完之后就跟安裝好了Windows一樣,目錄都列好了。
    今天又發(fā)現(xiàn)另一個圖形化的工具,Dism++,比這個操作更簡單。Dism是PowerShell內(nèi)置的命令,也是與鏡像有關(guān),也能掛載提取,但用了一下似乎提示權(quán)限有問題,Dism++是國內(nèi)開源愛好者自己開發(fā)的圖形化工具,與Dism沒有關(guān)系。
    13、好了,原版的Windows已經(jīng)準(zhǔn)備好,進(jìn)入Windows\System32\DriverStore\FileRepository目錄,搜索usbohci.sys,在usbport.inf_amd64_8e5f608c0111283d目錄下,點(diǎn)右鍵一看,也是沒簽名的:
    這不是坑爹嗎?你自己帶的東西都沒簽名,然后又不給用!!!!
    14、有點(diǎn)懷疑是Windows自己更新的時候修改了一些策略,導(dǎo)致之前可以用的不能用了,為了再次驗(yàn)證,又繼續(xù)下載了兩個版本的Windows10安裝光盤,分別是早期的1607和最新的1709,找到usbohci.sys,如下所示:
    從左到右依次為1607,1703,1709,均未簽名,基本可以判斷是Windows自己抽風(fēng)了。
    15、昨天晚上搞到12點(diǎn)多,搞定鼠標(biāo)后沒有重啟測試,今天早上開機(jī),果然發(fā)現(xiàn)鼠標(biāo)又不能用了,因?yàn)槲覜]有選擇禁用強(qiáng)制簽名選項(xiàng)來啟動,系統(tǒng)發(fā)現(xiàn)那個沒簽名的驅(qū)動,就把它停了,嘗試卸載,結(jié)果再裝也裝不上,于是只好又設(shè)置高級啟動,重新禁止強(qiáng)制簽名,進(jìn)入系統(tǒng),裝上驅(qū)動,恰好這時Windows又在后臺偷偷摸摸地更新,不知道更新了啥,讓我重啟。
    16、重啟之后,奇跡出現(xiàn),剛才明明提示沒有簽名強(qiáng)制安裝的驅(qū)動,現(xiàn)在居然正常啟動也沒問題了,而且查看驅(qū)動詳情的時候出現(xiàn)了矛盾的一幕:
    外面顯示數(shù)字簽名者:未經(jīng)數(shù)字簽名,里面的sys文件又顯示數(shù)字簽名者是Microsoft Windows,然而進(jìn)入C:\Windows\System32\drivers目錄,找到usbohci.sys,點(diǎn)右鍵,卻發(fā)現(xiàn)并沒有數(shù)字簽名:
    好吧,你開心就好,反正不要再禁我的鼠標(biāo)就行……
    感謝這次蛋疼的折騰之旅,讓我知道了驅(qū)動程序來自哪里,安裝日志在哪里,哪個軟件坑爹又沒用,怎么玩安裝盤,怎么用鍵盤操作鼠標(biāo),怎么進(jìn)入高級啟動界面……
    我為什么要知道這些??????????????為微軟的疏忽買單啊!!!!!
    啥都不說了,它又提示我重啟了,不知道又有什么奇跡會發(fā)生……
    posted @ 2017-11-19 12:43 amp@java 閱讀(1157) | 評論 (0)編輯 收藏

     每次換手機(jī),把舊手機(jī)的數(shù)據(jù)遷移到新手機(jī)就是個很麻煩的事情,幸好最近華為的“手機(jī)克隆”APP越來越強(qiáng)大,居然能夠把微信的聊天記錄包括圖片原封不動地遷移到新手機(jī)上,以前用微信自帶的聊天記錄轉(zhuǎn)移功能只能轉(zhuǎn)移文字信息,圖片視頻全部丟失,不知道現(xiàn)在的怎么樣。手機(jī)克隆還能把SD卡的內(nèi)容也轉(zhuǎn)移過來,基本滿足了需要。
    但是要把手機(jī)上的東西傳到電腦就沒那么簡單了,現(xiàn)在已經(jīng)沒有了以前的大容量存儲模式,只能選擇MTP模式,這種模式其實(shí)不是一個完整的文件系統(tǒng),有很多限制,所以一些傳統(tǒng)的軟件讀取不到,例如FastCopy是用不了的,用Windows自帶的文件管理器來復(fù)制,開始計算時間就要等很久,中間出了個錯就前功盡棄;還有通過手機(jī)上的APP訪問電腦共享的方式,在手機(jī)上復(fù)制也可以,但是同樣會莫名其妙卡死,F(xiàn)TP同理,折騰了好久,還是覺得自己動手比較好。
    MTP協(xié)議在維基百科里解釋得比較清楚:https://en.wikipedia.org/wiki/Media_Transfer_Protocol ,簡單點(diǎn)說就是:
    1、不是以塊設(shè)備的形式訪問,跟U盤不同;
    2、只能單線程訪問,不能同時進(jìn)行多個操作,只能一個接一個;
    3、控制權(quán)在設(shè)備上,對外展示的內(nèi)容由設(shè)備決定;
    4、默認(rèn)不能直接對文件進(jìn)行部分修改,只能復(fù)制過來修改完再復(fù)制回去,但Android對協(xié)議做了擴(kuò)展,能夠修改部分文件內(nèi)容;
    5、在Linux上有些軟件能夠把它掛載為文件系統(tǒng),這樣其他軟件就能像訪問普通文件系統(tǒng)一樣訪問了,但是Windows下似乎沒有。

    不過有人開發(fā)了一個在Windows下通過JNI實(shí)現(xiàn)的Java庫jmtp,項(xiàng)目托管在Google Code,被墻了,但是GitHub有人fork了一個,可以下載下來,我下載的是https://github.com/reindahl/jmtp
    里面包含了C++的代碼和Java的代碼,以及兩個已經(jīng)編譯好的dll文件,分別用于Win32和Win64,把其中一個dll文件放在工程目錄下,再把Java源代碼加入工程中即可使用,文檔比較簡陋,但是看test目錄下的MtpTest.java,基本可以摸到如何使用了,這個協(xié)議比較簡單,其實(shí)沒什么功能,我要的只是把文件復(fù)制到電腦上。
    根據(jù)MtpTest.java,稍微修改一下,做個遞歸復(fù)制即可把手機(jī)上的所有文件復(fù)制到電腦上:
    package test;

    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.math.BigInteger;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.rmi.server.SocketSecurityException;
    import java.util.ArrayList;


    import jmtp.PortableDevice;
    import jmtp.PortableDeviceFolderObject;
    import jmtp.PortableDeviceManager;
    import jmtp.PortableDeviceObject;
    import jmtp.PortableDeviceStorageObject;


    public class TestApp {

       

        
    public static void main(String[] args) {
            
    // TODO Auto-generated method stub
            
            ArrayList
    <PortableDeviceStorageObject> devices = new ArrayList<>();

            PortableDeviceManager manager 
    = new PortableDeviceManager();

            
    for (PortableDevice device : manager) {
                System.out.println(device);
                device.open();
                
                
    // Iterate over deviceObjects
                for (PortableDeviceObject object : device.getRootObjects()) {
                    String storageName
    =object.getName();
                    System.out.println(storageName);

                    
    // If the object is a storage object
                    if (object instanceof PortableDeviceStorageObject) {
                        PortableDeviceStorageObject storage 
    = (PortableDeviceStorageObject) object;
                        System.out.println(storage.getChildObjects().length);
                        
    for (PortableDeviceObject child : storage.getChildObjects()) {
                                copyall(child,
    "E:\\手機(jī)備份\\"+object.getName());
                        }
                    }
                }

                device.close();
                System.out.println(size);
            }

      
      
        }
        
        
    public static void copyall(PortableDeviceObject obj,String path) {

            if(obj instanceof PortableDeviceFolderObject) {
              

                String objName=obj.getName();
                
    if(objName.contains(":")) {
                    objName
    =objName.replace(':''');
                }
                String newPath 
    = path+"\\"+objName;
                System.out.println(
    "創(chuàng)建文件夾:"+newPath);
                
                File file = new File(newPath);
                if(!file.exists()) {
                    file.mkdirs();
                }
                for(PortableDeviceObject subObj:((PortableDeviceFolderObject) obj).getChildObjects()) {             
                    copyall(subObj,newPath);
                }
            }
            
    else {      
                
    if(obj.getName().contains(":"))
                    
    return;
                System.out.println(
    "開始復(fù)制文件到:"+path+"\\"+obj.getName());
                File file 
    = new File(path);
                obj.copy(file.toPath());                     
                System.out.println(
    "文件復(fù)制完成!");
            }
        }

    }
    其中發(fā)現(xiàn)有點(diǎn)問題:
    1、Android設(shè)備文件名里是可以包含冒號(:)的,但Windows是不可以的,所以復(fù)制到這些文件的時候會有問題,于是遇到目錄名這樣就把它改為中文的冒號(:),但是遇到文件名這樣就不行了,因?yàn)檫@個庫的copy函數(shù)只需要指定目標(biāo)目錄,不需要指定目標(biāo)文件名,所以這些文件只能放棄;
    2、Android手機(jī)的MTP協(xié)議是由“媒體存儲”這個系統(tǒng)APP控制的,有時候手機(jī)上可以看到的文件,通過MTP訪問卻怎么也看不到,重啟手機(jī)也不行,應(yīng)該就是這個APP沒有更新數(shù)據(jù),需要把它的系統(tǒng)數(shù)據(jù)清除掉,等它重建完重新訪問就可以看到了,不過這個重建時間非常長,可以查看它數(shù)據(jù)占用的空間,剛清除之后會發(fā)現(xiàn)它占用的空間會不斷增長,到了不增長的時候就是重建完了,就可以正常訪問了;
    3、這個庫有時候還有點(diǎn)bug,有一次發(fā)現(xiàn)它讀取到的文件和文件夾都沒有了最后一個.后面的部分,所以總是卡住,重新插拔一下手機(jī)數(shù)據(jù)線又沒問題了;
    4、為了避免復(fù)制了半天結(jié)果發(fā)現(xiàn)不完整,又要重來,最好在復(fù)制前先統(tǒng)計一下文件大小,看看跟手機(jī)上看到的占用存儲空間是不是一致,對于MTP設(shè)備上的文件,可以通過getSize函數(shù)得到大小,把上面復(fù)制操作改為大小累加即可,速度比復(fù)制快一些,不過由于小文件太多,也不會快很多。

    把手機(jī)里的文件復(fù)制到電腦后,通過一些簡單的分析,發(fā)現(xiàn)有很多其實(shí)是垃圾來的,也可以為手機(jī)空間清理提供參考,因?yàn)樵陔娔X上分析起來比在手機(jī)上方便一些。例如一些視頻APP的緩存,居然超過1G,占用了寶貴的內(nèi)部存儲空間,之前一直都沒發(fā)現(xiàn),通過電腦里的按文件大小搜索才發(fā)現(xiàn)。
    posted @ 2017-11-17 14:54 amp@java 閱讀(2256) | 評論 (0)編輯 收藏

    09款老速騰,不支持USB和AUX,要聽歌除了CD以外,就是刻錄在CD上的MP3了,以前不知道用什么軟件刻錄了一張碟,能夠完美地顯示中文文件名和ID3信息,前幾天用ImgBurn刻了一張,發(fā)現(xiàn)中文是亂碼,開始以為是ID3信息顯示亂碼,于是下載了一個Mp3Tag,把所有ID3信息都清除,結(jié)果顯示文件名依然亂碼,重新寫入ID3信息,發(fā)現(xiàn)ID3可以正常顯示,但文件名還是亂碼。
    于是就把原來那張可以正常顯示中文的碟拿來研究一下,發(fā)現(xiàn)它的ID3標(biāo)簽只是ID3v1,而后來重新寫入的ID3是ID3v2.3,兩個都可以正常顯示中文,說明ID3信息是正常的,文件名亂碼不是這個問題。
    但是不知道用什么軟件來顯示光盤的文件系統(tǒng),只能一次次摸索。
    幸好有一張CD-RW可以反復(fù)嘗試。
    ImgBurn默認(rèn)是使用ISO9660+UDF,而ISO 9660則使用最老的ISO 9660文件系統(tǒng),也就是1988版本,文件名默認(rèn)是不支持中文的,不知道是不是這個原因,于是就把文件系統(tǒng)改為ISO 9660+Joliet,如下圖:

    并且把ISO 9660標(biāo)準(zhǔn)改為1999:

    可能是因?yàn)樽址幋a那里改為了ASCII,所以就好了。
    后來又嘗試只使用UDF文件系統(tǒng),結(jié)果認(rèn)不出碟。



    所以,目前能夠使用中文的環(huán)境其實(shí)就是:
    ImgBurn使用ISO 9660 1999標(biāo)準(zhǔn);
    ID3使用v1或v2.3都可以。

    posted @ 2017-02-10 09:17 amp@java 閱讀(405) | 評論 (0)編輯 收藏

    最近新部署了一個信息系統(tǒng),廠家居然沒有升級方案,所有數(shù)據(jù)都要重新輸入,包括用戶、角色等都要重新配置,真是操蛋。要是一個個錄入簡直是日狗了,這些用戶在其他信息系統(tǒng)早已存在,但是每個都復(fù)制粘貼提交一遍也不是辦法,于是就想用程序自動完成這些操作。步驟如下:
    1、從其他信息系統(tǒng)的數(shù)據(jù)庫導(dǎo)出用戶信息,也可以直接從其他信息系統(tǒng)的界面把所有用戶信息復(fù)制下來放在一個文本文件里,反正就是準(zhǔn)備好數(shù)據(jù)源;
    2、在需要錄入用戶信息的系統(tǒng)中,用人工操作的方式登錄系統(tǒng),并錄入一個用戶,同時用Wireshark抓包,查看整個過程要提交一些什么樣的表單數(shù)據(jù);
    3、在程序中用httpclient提交同樣的數(shù)據(jù),完成登錄,并從第1步的數(shù)據(jù)源中讀取用戶信息,然后循環(huán)提交錄入用戶所需的數(shù)據(jù),完成用戶的錄入;
    4、新系統(tǒng)沒有默認(rèn)的用戶角色,是需要一個個修改的,是根據(jù)用戶的ID來確定當(dāng)前修改的用戶,并且提交一個角色I(xiàn)D來進(jìn)行設(shè)定,因此需要首先獲取用戶的ID,然后根據(jù)該ID來提交角色I(xiàn)D,而用戶ID是通過用戶列表頁面獲取到的,因此還需要通過正則表達(dá)式來獲取所有用戶的ID,然后循環(huán)提交角色I(xiàn)D,完成角色設(shè)定。

    花了不少時間才搞定,有幾個地方需要注意:
    1、如果表單數(shù)據(jù)不包含中文,直接把表單的Name和Value加在HttpPost的URL的?后面即可,不需要專門建立NameValuePair,如下所示:
    HttpPost httppost = new HttpPost("http://1.1.1.1/test/adduser?userid=abc&username=efg");
    httpclient.execute(httppost);

    但是,如果表單數(shù)據(jù)包含中文,例如姓名,用這種方式提交的表單數(shù)據(jù)會出現(xiàn)亂碼,即使通過URLEncoder進(jìn)行編碼后再發(fā)也不行,必須建立NameValuePair,再加到HttpPost的Entity里面,如下所示:
    HttpPost httppost = new HttpPost("http://1.1.1.1/test/adduser?userid=abc");
    List
    <NameValuePair> nvps = new ArrayList<NameValuePair>();
    nvps.add(
    new BasicNameValuePair("username","張三"));
    httppost.setEntity(
    new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
    httpclient.execute(httppost);

    2、用于網(wǎng)頁內(nèi)容查找的正則表達(dá)式的使用方式一般為:
    Pattern p = Pattern.compile(".*?abc(whattoget)123.*?");
    Matcher m = p.matcher(line);
    if(m.matches()){
         String whattoget 
    = m.group(1);
    }
    ".*?abc(whattoget)123.*?"就是一個正則表達(dá)式,如果用于匹配一行的時候,由于要查找的內(nèi)容是在行中間,所以前后需要加上.*?,表示前后可以是任意字符,也可以什么都沒有,而表達(dá)式中間的(whattoget)就表示一個group,編號為1,編號為0的group是整個匹配的字符串,找到之后提取group(1)即可得到想要的內(nèi)容。
    測試正則表達(dá)式是一項(xiàng)很麻煩的工作,不過有個很好的軟件可以完成此工作:RegexBuddy,支持各種語言的正則表達(dá)式的調(diào)試。
    學(xué)習(xí)正則表達(dá)式的寶典是《Mastering Regular Expression》。
    posted @ 2016-01-12 15:54 amp@java 閱讀(3576) | 評論 (1)編輯 收藏

    今天遇到一個非常奇怪的問題,有臺裝XP的電腦,插上USB鍵盤沒反應(yīng),還以為是鍵盤壞了,又找來兩個不同型號的鍵盤,依然不行,又以為是USB接口壞了,結(jié)果在電腦啟動的時候又可以按F2進(jìn)入BIOS,這樣就只有一個原因,Windows的驅(qū)動沒裝上了。
    幸好這電腦還有傳統(tǒng)的PS/2口,而且插上就能識別,否則連Windows都進(jìn)不去,因?yàn)榘碈trl+Alt+Del沒反應(yīng)。
    進(jìn)去之后提示安裝USB鍵盤驅(qū)動,到最后一步提示安裝失敗,原因是拒絕訪問。
    上網(wǎng)搜了一下,安裝驅(qū)動拒絕訪問的其中一個原因是注冊表有個鍵的權(quán)限設(shè)置有問題,改過來即可,但是我打開注冊表,連那個鍵都沒找到,不是這個原因。
    不過從這個解決方案中也知道了驅(qū)動安裝的日志是在Windows目錄下的setupapi.log文件里面,于是打開那個文件,發(fā)現(xiàn)每次安裝都有兩個拒絕訪問的錯誤,但并沒有說是注冊表拒絕訪問,在拒絕訪問之前,還提到一個叫MlCoInst.dll的文件沒有簽名。
    上網(wǎng)搜MlCoInst.dll,沒有找到任何結(jié)果,在System32目錄下找到它,看屬性,果然沒有簽名,是個三無文件,不知道為什么每次安裝驅(qū)動都要調(diào)用它。
    日志里面還提到了“共同安裝程序”,似乎和CoInst有點(diǎn)關(guān)聯(lián),于是又查了一下,原來安裝驅(qū)動的時候可以通過調(diào)用“共同安裝程序”來實(shí)現(xiàn)某些目的,例如修改驅(qū)動程序的簽名狀態(tài),欺騙操作系統(tǒng),這樣就可以只安裝一次驅(qū)動即可,不用每次插入都安裝一次。
    于是嘗試把MlCoInst.dll刪除,提示刪除失敗。
    在注冊表里面搜索MlCoInst.dll,把所有找到的鍵值都刪除,再次插拔鍵盤,順利安裝完畢,刪除MlCoInst.dll,也成功了,果然是它的問題。

    這個應(yīng)該是某個USB設(shè)備的驅(qū)動引進(jìn)來的,而且修改了usb.inf,每次安裝任何USB設(shè)備都要調(diào)用它,但它可能與Windows的簽名機(jī)制有沖突,所以導(dǎo)致安裝失敗,真是坑爹!
    posted @ 2015-04-02 17:04 amp@java 閱讀(3605) | 評論 (0)編輯 收藏

    做GUI程序的時候,通常有個后臺工作線程在努力工作,但是中間又需要一些暫停,而關(guān)閉程序的時候,必須立即結(jié)束那個線程,退出程序,也有的時候需要停止后臺線程,但不關(guān)閉程序。例如,做一個目錄監(jiān)控程序,發(fā)現(xiàn)目錄中有文件的時候,執(zhí)行一定的操作,執(zhí)行完之后沒有文件了,就要暫停一下,過幾秒或幾分鐘再次檢測,這時候就要對線程進(jìn)行暫停操作,如果在暫停的時候,用戶要關(guān)閉程序,就必須馬上停止線程,如果用戶需要暫停檢測,按下某個按鈕后,需要讓線程馬上停止,但再次按下某個按鈕,線程又必須馬上開始。

    以前我都是通過檢測停止標(biāo)記和用Thread.sleep(time)來完成的,后臺線程的每次循環(huán)都要檢查停止標(biāo)記,如果發(fā)現(xiàn)停止標(biāo)記已設(shè)定,就不再循環(huán),退出線程,在線程內(nèi)部,如果需要暫停,就執(zhí)行Thread.sleep(time)。通過把線程的setDaemon(true)方法,還可以讓線程作為后臺線程,當(dāng)圖形界面關(guān)閉后,線程也自動退出。

    但是,這種方式有個問題,如果我需要在圖形界面上點(diǎn)擊按鈕來停止線程,但并不退出程序,而點(diǎn)擊按鈕的時候線程正處于sleep狀態(tài),就對它沒有任何辦法,只能讓它醒過來再操作,如果sleep的時間比較長,例如1分鐘,那么點(diǎn)擊按鈕之后,用戶最多要等1分鐘才能把線程停下來。當(dāng)然,Thread對象有個interrupt方法,但是已經(jīng)被標(biāo)記為過期,一般不建議使用了。感謝評論中watchzerg的提醒,Thread的interrupt()并沒有標(biāo)記為過期,可以按照他的說法來操作,更為簡單。

    怎么讓線程能暫停,又能隨時叫醒呢?原來Java里最原始的對象Object就自帶此功能。

    每個Object都有wait(time)和notify()方法,前者就是讓擁有該Obejct的線程處于暫停狀態(tài),后者則讓線程馬上喚醒,通過這兩個方法,就能夠滿足上述的所有要求。

    首先,建立一個同步對象:
    Object syncObj = new Object();

    然后在線程中需要暫停的地方,調(diào)用該對象的wait(time)方法:
    synchronized (syncObj) {
           syncObj.wait(60*1000);
    }

    在圖形界面的按鈕監(jiān)聽事件中,對該對象執(zhí)行notify()方法:
            button_1.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {

                    thread.setStop(true);
                    synchronized (syncObj) {
                            syncObj.notify();
                     }
                    //為了等待線程退出,還可以加上以下語句:
                    thread.join();

                }
            });

    posted @ 2015-03-10 16:52 amp@java 閱讀(7692) | 評論 (2)編輯 收藏

    Eclipse有個功能就是把整個項(xiàng)目打包成一個可執(zhí)行的Jar文件,里面包含了所有項(xiàng)目引用了的庫,如果電腦上安裝了JRE,直接雙擊就可以啟動,看起來很方便,如下圖所示:

    可以選擇把所有類庫打包進(jìn)去,也就是Jar里面還包含一堆Jar:

    還可以生成ant腳本:


    生成的jar文件,可以直接通過java -jar xx.jar啟動,簡單快捷。


    然而,這樣導(dǎo)出來的可執(zhí)行jar,啟動速度卻非常慢,這跟包的大小有關(guān)。有個項(xiàng)目導(dǎo)出來的包有40MB,結(jié)果啟動需要近一分鐘,在性能差的電腦上,甚至要幾分鐘,就是你執(zhí)行完命令后,沒有任何界面顯示,但是查看任務(wù)管理器發(fā)現(xiàn)java進(jìn)程的CPU占用率在浮動,說明正在努力啟動,過了一段時間之后界面突然顯示出來,簡直讓人崩潰。可是在Eclipse里面運(yùn)行,卻是一點(diǎn)就開。

    我開始嘗試縮小導(dǎo)出的包。但是Eclipse的導(dǎo)出對話框并沒有提供需要打包哪些庫的選項(xiàng),都是默認(rèn)把所有庫都打包進(jìn)去,但是它可以生成ant腳本,可以通過編輯ant腳本的方式來減少不必要的庫。經(jīng)過多次嘗試,終于把40MB的包縮成了17MB,啟動速度快了一些,但是依然需要半分鐘以上。

    后來覺得,能不能不打包直接運(yùn)行呢?于是把導(dǎo)出來的包用壓縮軟件解壓,再把里面包含的jar包繼續(xù)解壓,最后得到一堆沒有壓縮的class文件,再通過指定classpath的方式,直接運(yùn)行程序入口class,發(fā)現(xiàn)啟動速度和在Eclipse里面一樣,一點(diǎn)就開。

    打包的好處是部署簡單,只需要一個文件,但帶來的缺點(diǎn)實(shí)在不能忍,打散的方式部署起來稍微難一點(diǎn),但是啟動速度夠快,對普通用戶來說,這個才是最重要的。

    當(dāng)然,還有一種方式是像Eclipse那樣,啟動時顯示一個圖片,底下一個進(jìn)度條顯示啟動進(jìn)度,不過這樣也加大了工作量,而且每次都要等那進(jìn)度條,實(shí)際上也很煩。
    posted @ 2015-03-10 15:07 amp@java 閱讀(5143) | 評論 (0)編輯 收藏

         摘要: JMF太老了,各種問題得不到解決,Oracle也沒再升級過,如果能找到新東西,最好能把它扔掉。最近OpenCV比較火,還有人用Java封裝了OpenCV,成立了JavaCV項(xiàng)目,通過改造VideoInput這個基于C語言的項(xiàng)目,能夠用Java來調(diào)用攝像頭,JMF可以扔掉了。如果想測試,非常簡單,把那些編譯好的jar文件放入Build Path即可,如果是在Windows X86環(huán)境下,則只需要把帶...  閱讀全文
    posted @ 2015-02-15 11:41 amp@java 閱讀(10432) | 評論 (7)編輯 收藏

    其實(shí)我覺得用java結(jié)合SQL來做同樣的事情更簡單,但是EXCEL的好處是不用編程,雖然里面有好多陷阱,但是掌握之后能夠熟練運(yùn)用還是比每次都編個程序更簡單。VLOOKUP函數(shù)的使用比較復(fù)雜,搞了好久都不明白,終于找到了下面這篇文章,解決了很多問題。

    以下是轉(zhuǎn)載文章,原來的出處不知道是哪里,應(yīng)該是來自

    http://www.excelpx.com
    但具體的地址不詳。



    VLOOKUP函數(shù)是Excel中幾個最重函數(shù)之一,為了方便大家學(xué)習(xí),蘭色幻想特針對VLOOKUP函數(shù)的使用和擴(kuò)展應(yīng)用,進(jìn)行一次全面綜合的說明。本文為入門部分

         一、入門級

          VLOOKUP是一個查找函數(shù),給定一個查找的目標(biāo),它就能從指定的查找區(qū)域中查找返回想要查找到的值。它的基本語法為:

          VLOOKUP(查找目標(biāo)查找范圍返回值的列數(shù)精確OR模糊查找)

    下面以一個實(shí)例來介紹一下這四個參數(shù)的使用

         例1:如下圖所示,要求根據(jù)表二中的姓名,查找姓名所對應(yīng)的年齡。  

       公式:B13 =VLOOKUP(A13,$B$2:$D$8,3,0)  

       參數(shù)說明:

           1 查找目標(biāo):就是你指定的查找的內(nèi)容或單元格引用。本例中表二A列的姓名就是查找目標(biāo)。我們要根據(jù)表二的“姓名”在表一中A列進(jìn)行查找。

            公式:B13 =VLOOKUP(A13,$B$2:$D$8,3,0)   

           2 查找范圍(VLOOKUP(A13,$B$2:$D$8,3,0) : 指定了查找目標(biāo),如果沒有說從哪里查找,EXCEL肯定會很為難。所以下一步我們就要指定從哪個范圍中進(jìn)行查找。VLOOKUP的這第二個參數(shù)可以從一個 單元格區(qū)域中查找,也可以從一個常量數(shù)組或內(nèi)存數(shù)組中查找。本例中要從表一中進(jìn)行查找,那么范圍我們要怎么指定呢?這里也是極易出錯的地方。大家一定要注 意,給定的第二個參數(shù)查找范圍要符合以下條件才不會出錯:

            A 查找目標(biāo)一定要在該區(qū)域的第一列。本例中查找表二的姓名,那么姓名所對應(yīng)的表一的姓名列,那么表一的姓名列(列)一定要是查找區(qū)域的第一列。象本例中,給定的區(qū)域要從第二列開始,即$B$2:$D$8,而不能是$A$2:$D$8。因?yàn)椴檎业?#8220;姓名”不在$A$2:$D$8區(qū)域的第一列。

            B 該區(qū)域中一定要包含要返回值所在的列,本例中要返回的值是年齡。年齡列(表一的D列)一定要包括在這個范圍內(nèi),即:$B$2:$D$8,如果寫成$B$2:$C$8就是錯的。

           3 返回值的列數(shù)(B13 =VLOOKUP(A13,$B$2:$D$8,3,0))。這是VLOOKUP第3個參數(shù)。它是一個整數(shù)值。它怎么得來的呢。它是“返回值”在第二個參數(shù)給定的區(qū)域中的列數(shù)。本例中我們要返回的是“年齡”,它是第二個參數(shù)查找范圍$B$2:$D$8的第3列。這里一定要注意,列數(shù)不是在工作表中的列數(shù)(不是第4列),而是在查找范圍區(qū)域的第幾列。如果本例中要是查找姓名所對應(yīng)的性別,第3個參數(shù)的值應(yīng)該設(shè)置為多少呢。答案是2。因?yàn)樾詣e在$B$2:$D$8的第2列中。

           4 精確OR模糊查找(VLOOKUP(A13,$B$2:$D$8,3,0)  ),最后一個參數(shù)是決定函數(shù)精確和模糊查找的關(guān)鍵。精確即完全一樣,模糊即包含的意思。第4個參數(shù)如果指定值是0或FALSE就表示精確查找,而值為1 或TRUE時則表示模糊。這里蘭色提醒大家切記切記,在使用VLOOKUP時千萬不要把這個參數(shù)給漏掉了,如果缺少這個參數(shù)默為值為模糊查找,我們就無法精確查找到結(jié)果了。  

          好了,關(guān)于VLOOKUP函數(shù)的入門級應(yīng)用就說到這里,VLOOKUP函數(shù)可不只是這么簡單的查找,我們講的還只是1/10的用法。其他的沒法在一篇文章中說明。敬請期待“VLOOKUP的使用方法-進(jìn)階篇”吧。

     

    上一講咱們學(xué)習(xí)了VLOOKUP的基本用法和示例,本講將介紹VLOOKUP在使用中的一些小技巧。

    Excel函數(shù)速成教程全系列(包括VLOOKUP函數(shù),IF函數(shù),offset函數(shù),sumif函數(shù)等66個函數(shù))預(yù)計6月初全部錄制完成,現(xiàn)已在淘寶開始預(yù)訂(8折優(yōu)惠),地址:http://item.taobao.com/item.htm?id=17500884347

    一、VLOOKUP多行查找時復(fù)制公式的問題

        VLOOKUP函數(shù)的第三個參數(shù)是查找返回值所在的列數(shù),如果我們需要查找返回多列時,這個列數(shù)值需要一個個的更改,比如返回第2列的,參數(shù)設(shè)置為2,如 果需要返回第3列的,就需要把值改為3。。。如果有十幾列會很麻煩的。那么能不能讓第3個參數(shù)自動變呢?向后復(fù)制時自動變?yōu)?,3,4,5。。。   

        在EXCEL中有一個函數(shù)COLUMN,它可以返回指定單元格的列數(shù),比如

             =COLUMNS(A1) 返回值1

             =COLUMNS(B1) 返回值2

       而單元格引用復(fù)制時會自動發(fā)生變化,即A1隨公式向右復(fù)制時會變成B1,C1,D1。。這樣我們用COLUMN函數(shù)就可以轉(zhuǎn)換成數(shù)字1,2,3,4。。。 

        例:下例中需要同時查找性別,年齡,身高,體重。

       

         公式:=VLOOKUP($A13,$B$2:$F$8,COLUMN(B1),0)

      公式說明:這里就是使用COLUMN(B1)轉(zhuǎn)化成可以自動遞增的數(shù)字。

    二、VLOOKUP查找出現(xiàn)錯誤值的問題。

        1、如何避免出現(xiàn)錯誤值。

         EXCEL2003 在VLOOKUP查找不到,就#N/A的錯誤值,我們可以利用錯誤處理函數(shù)把錯誤值轉(zhuǎn)換成0或空值。

          即:=IF(ISERROR(VLOOKUP(參數(shù)略)),"",VLOOKUP(參數(shù)略)

         EXCEL2007,EXCEL2010中提供了一個新函數(shù)IFERROR,處理起來比EXCEL2003簡單多了。

         IFERROR(VLOOKUP(),"") 

        2、VLOOKUP函數(shù)查找時出現(xiàn)錯誤值的幾個原因

          A、實(shí)在是沒有所要查找到的值

          B、查找的字符串或被查找的字符中含有空格或看不見的空字符,驗(yàn)證方法是用=號對比一下,如果結(jié)果是FALSE,就表示兩個單元格看上去相同,其實(shí)結(jié)果不同。

          C、參數(shù)設(shè)置錯誤。VLOOKUP的最后一個參數(shù)沒有設(shè)置成1或者是沒有設(shè)置掉。第二個參數(shù)數(shù)據(jù)源區(qū)域,查找的值不是區(qū)域的第一列,或者需要反回的字段不在區(qū)域里,參數(shù)設(shè)置在入門講里已注明,請參閱。

         D、數(shù)值格式不同,如果查找值是文本,被查找的是數(shù)字類型,就會查找不到。解決方法是把查找的轉(zhuǎn)換成文本或數(shù)值,轉(zhuǎn)換方法如下:

         文本轉(zhuǎn)換成數(shù)值:*1或--或/1

         數(shù)值轉(zhuǎn)抱成文本:&""  

         VLOOKUP函數(shù)的初級篇就說到這里了,咱們下一講將介紹VLOOKUP的模糊查找有、反向查找等。

     

     在學(xué)習(xí)了VLOOKUP的入門和初級篇后,本文將帶將大家學(xué)習(xí)VLOOKUP的進(jìn)階篇:VLOOKUP的模糊查找。

        一、字符的模糊查找    

            在A列我們知道如何查找型號為“AAA”的產(chǎn)品所對應(yīng)的B列價格,即:

        =VLOOKUP(C1,A:B,2,0)

           如果我們需要查找包含“AAA”的產(chǎn)品名稱怎么表示呢?如下圖表中所示。

         公式=VLOOKUP("*"&A10&"*",A2:B6,2,0)  

        公式說明:VLOOKUP的第一個參數(shù)允許使用通配符“*”來表示包含的意思,把*放在字符的兩邊,即"*" & 字符 & "*"。

       二、數(shù)字的區(qū)間查找

          數(shù)字的區(qū)間查找即給定多個區(qū)間,指定一個數(shù)就可以查找出它在哪個區(qū)間并返回這個區(qū)間所對應(yīng)的值。

        在VLOOKUP入門中我們提示VLOOKUP的第4個參數(shù),如果為0或FALSE是精確查找,如果是1或TRUE或省略則為模糊查找,那么實(shí)現(xiàn)區(qū)間查找正是第4個參數(shù)的模糊查找應(yīng)用。

        首先我們需要了解一下VLOOKUP函數(shù)模糊查找的兩個重要規(guī)則:

        1、引用的數(shù)字區(qū)域一定要從小到大排序。雜亂的數(shù)字是無法準(zhǔn)確查找到的。如下面A列符合模糊查找的前題,B列則不符合 

        

        2、模糊查找的原理是給一定個數(shù),它會找到和它最接近,但比它小的那個數(shù)。詳見下圖說明。

        

       最后看一個實(shí)例: 

        例:如下圖所示,要求根據(jù)上面的提成比率表,在提成表計算表中計算每個銷售額的提成比率和提成額。

        

       公式:=VLOOKUP(A11,$A$3:$B$7,2)

       公式說明:

        1、上述公式省略了VLOOKUP最后一個參數(shù),相當(dāng)于把第四個參數(shù)設(shè)置成1或TRUE。這表示VLOOKUP要進(jìn)行數(shù)字的區(qū)間查找。

        2、圖中公式中在查找5000時返回比率表0所對應(yīng)的比率1%,原因是0和10000與5000最接近,但VLOOKUP只選比查找值小的那一個,所以公式會返回0所對應(yīng)的比率1%。

     

     前言:前面我們分別學(xué)習(xí)了VLOOKUP函數(shù)的入門、初級和進(jìn)階篇。今天我們學(xué)習(xí)VLOOKUP函數(shù)的高級應(yīng)用部分-VLOOKUP函數(shù)的數(shù)組應(yīng)用。(本文由蘭色幻想原創(chuàng),轉(zhuǎn)載請注明轉(zhuǎn)自excel精英培訓(xùn)

     一、VLOOKUP的反向查找。

        一般情況下,VLOOKUP函數(shù)只能從左向右查找。但如果需要從右向右查找,則需要把區(qū)域進(jìn)行“乾坤大挪移”,把列的位置用數(shù)組互換一下。

        例1:要求在如下圖所示表中的姓名反查工號。

         

        公式:=VLOOKUP(A9,IF({1,0},B2:B5,A2:A5),2,0)

        公式剖析:

            1、這里其實(shí)不是VLOOKUP可以實(shí)現(xiàn)從右至右的查找,而是利用IF函數(shù)的數(shù)組效應(yīng)把兩列換位重新組合后,再按正常的從左至右查找。

            2、IF({1,0},B2:B5,A2:A5)這是本公式中最重要的組成部分。在EXCEL函數(shù)中使用數(shù)組時(前提時該函數(shù)的參數(shù)支持?jǐn)?shù)組),返回的結(jié) 果也會是一個數(shù)組。這里1和0不是實(shí)際意義上的數(shù)字,而是1相關(guān)于TRUE,0相當(dāng)于FALSE,當(dāng)為1時,它會返回IF的第二個參數(shù)(B列),為0時返 回第二個參數(shù)(A列)。根據(jù)數(shù)組運(yùn)算返回數(shù)組,所以使用IF后的結(jié)果返回一個數(shù)組(非單元格區(qū)域):{"張一","A001";"趙 三","A002";"楊五","A003";"孫二","A004"}

     二、VLOOKUP函數(shù)的多條件查找。

          VLOOKUP函數(shù)需要借用數(shù)組才能實(shí)現(xiàn)多條件查找。

         例2:要求根據(jù)部門和姓名查找C列的加班時間。

         分析:我們可以延用例1的思路,我們的努力方向不是讓VLOOKUP本身實(shí)現(xiàn)多條件查找,而是想辦法重構(gòu)一個數(shù)組。多個條件我們可以用&連接在一起,同樣兩列我們也可以連接成一列數(shù)據(jù),然后用IF函數(shù)進(jìn)行組合。

        公式:{=VLOOKUP(A9&B9,IF({1,0},A2:A5&B2:B5,C2:C5),2,0)}

        公式剖析:

           1、A9&B9 把兩個條件連接在一起。把他們做為一個整體進(jìn)行查找。

           2、A2:A5&B2:B5,和條件連接相對應(yīng),把部分和姓名列也連接在一起,作為一個待查找的整體。

           3、IF({1,0},A2:A5&B2:B5,C2:C5) 用IF({1,0}把連接后的兩列與C列數(shù)據(jù)合并成一個兩列的內(nèi)存數(shù)組。按F9后可以查看的結(jié)果為:

           {"銷售張一",1;"銷售趙三",5;"人事楊五",3;"銷售趙三",6}

           4、完成了數(shù)組的重構(gòu)后,接下來就是VLOOKUP的基本查找功能了,另外公式中含有多個數(shù)據(jù)與多個數(shù)據(jù)運(yùn)算(A2:A5&B2:B5),,所以必須以數(shù)組形式輸入,即按ctrl+shift后按ENTER結(jié)束輸入。

         三、VLOOKUP函數(shù)的批量查找。

         VLOOKUP一般情況下只能查找一個,那么多項(xiàng)該怎么查找呢?

         例3 要求把如圖表中所有張一的消費(fèi)金額全列出來

         分析:經(jīng)過前面的學(xué)習(xí),我們也有這樣一個思路,我們在實(shí)現(xiàn)復(fù)雜的查找時,努力的方向是怎么重構(gòu)一個查找內(nèi)容和查找的區(qū)域。要想實(shí)現(xiàn)多項(xiàng)查找,我們可以對查找的內(nèi)容進(jìn)行編號,第一個出現(xiàn)的是后面連接1,第二個出現(xiàn)的連接2。。。

         公式:{=VLOOKUP(B$9&ROW(A1),IF({1,0},$B$2:$B$6&COUNTIF(INDIRECT("b2:b"&ROW($2:$6)),B$9),$C$2:$C$6),2,)}

         公式剖析:

            1、B$9&ROW(A1) 連接序號,公式向下復(fù)制時會變成B$9連接1,2,3

            2、給所有的張一進(jìn)行編號。要想生成編號,就需要生成一個不斷擴(kuò)充的區(qū)域(INDIRECT("b2:b"&ROW($2:$6)),然后在這個逐行擴(kuò)充的區(qū)域內(nèi)統(tǒng)計“張一”的個數(shù),在連接上$B$2:$B$6后就可以對所有的張一進(jìn)行編號了。

           3、IF({1,0}把編號后的B列和C組重構(gòu)成一個兩列數(shù)組

         通過以上的講解,我們需要知道,VLOOKUP函數(shù)的基本用法是固定的,要實(shí)現(xiàn)高級查找,就需要借助其他函數(shù)來重構(gòu)查找內(nèi)容和查找數(shù)組。

         至此VLOOKUP函數(shù)從入門到高級的四篇VLOOKUP函數(shù)使用教程全部結(jié)束了,VLOOKUP函數(shù)在數(shù)組運(yùn)算中還有著其他應(yīng)用,但只是配角了,所以本系列不再介紹。由于筆者水平有限,不免有錯漏之處,請大家多多指點(diǎn)。

    posted @ 2014-12-16 09:10 amp@java 閱讀(520) | 評論 (0)編輯 收藏

    JMF(Java Media Framework)是Java平臺使用攝像頭、麥克風(fēng)等媒體設(shè)備的應(yīng)用程序框架,但到了2.1.1e就不再更新,在Windows 7 X64上還能正常運(yùn)行,只是安裝的界面讓你感覺回到了Windows98的時代。


    不過年代久遠(yuǎn)的東西,雖然還能用,但可能會遇到一些奇怪的問題,折騰了兩個月,發(fā)現(xiàn)了兩個比較大的問題:

    第一個是在Windows 7 x64上提示攝像頭初始化失敗的問題。這個問題很奇怪,電腦剛開機(jī)的時候可以順利找到一次攝像頭并正常操作,但是第二次就會提示攝像頭初始化失敗。有人提出的解決方法是安裝一個叫ManyCamera的程序,這個程序可以把一個攝像頭供多個程序同時使用,其實(shí)就等于中間加了一層轉(zhuǎn)換,效果會有點(diǎn)差別,免費(fèi)版還會加上水印,要求比較高的人可能會不爽,但是目前找不到其他辦法。

    第二個是在程序中找不到攝像頭,不光找不到攝像頭,其他媒體設(shè)備通通找不到,使用以下語句:
    vector = CaptureDeviceManager.getDeviceList ( null )
    按照文檔說明是返回所有媒體設(shè)備,但每次vector都是null。
    在Eclipse中運(yùn)行又能正常,導(dǎo)出成jar之后運(yùn)行就會找不到攝像頭。
    原因在于找不到j(luò)mf.properities文件,該文件包含所有檢測到的媒體設(shè)備的信息,最簡單的解決方法就是把JMF安裝目錄下lib子目錄中的jmf.properties文件復(fù)制到最后運(yùn)行的jar所在的目錄,不過如果攝像頭改過的話,重新檢測后要把新的文件復(fù)制到j(luò)ar目錄,因?yàn)闄z測到的媒體設(shè)備信息都會存放在JMF安裝目錄里面的jmf.properties文件里。

    StackOverflow里面有個人對這個問題解釋得比較清楚:
    http://stackoverflow.com/questions/8768142/java-capturedevicemanagergetdevicelist-is-empty


    雖然問題解決了,但是還是不明白為何在Eclipse中可以正常運(yùn)行,導(dǎo)出jar后運(yùn)行卻找不到攝像頭,即使把JMF所有jar和lib目錄都加入系統(tǒng)的CLASSPATH環(huán)境變量里還是不行。


    另外,JMF安裝程序會自動把它的jar和lib目錄加入系統(tǒng)的%CLASSPATH%環(huán)境變量,但是如果你卸載了再重新安裝到其他目錄,并不會改變%CLASSPATH%的值,需要手動修改。不過這個環(huán)境變量似乎沒啥用處。
    最好不要把JMF安裝到默認(rèn)的Program Files目錄,可能會運(yùn)行不了,安裝到短目錄會比較保險,它似乎還是只認(rèn)Dos時代的8.3目錄結(jié)構(gòu),但偏偏又默認(rèn)安裝到Program Files里面。
    posted @ 2014-07-01 10:33 amp@java 閱讀(7275) | 評論 (0)編輯 收藏

    其實(shí)我也搞不懂Windows的域,反正能用就行了。
    但是最近有一臺客戶端的時間改不了,總是提示特權(quán)級不夠,按理說應(yīng)該是組策略限制了,但是我把那臺計算機(jī)從包含該組策略的OU中移出來,還是不行,這就奇怪了,難道組策略不是指針對OU里面的成員的嗎?百思不得其解啊,最后只能在BIOS里面把時間改了。
    今天發(fā)現(xiàn)我自己的電腦設(shè)置不了屏幕保護(hù),也是組策略限制了,然后把我的用戶和計算機(jī)都移出了組策略應(yīng)用的OU,結(jié)果發(fā)現(xiàn)還是設(shè)置不了,這下肯定是組策略的應(yīng)用上有問題了。
    搜索了半天發(fā)現(xiàn)有個叫rsop.msc的管理工具,可以看到某用戶在某計算機(jī)上應(yīng)用的組策略,結(jié)果發(fā)現(xiàn)我還是應(yīng)用之前的組策略,但是計算機(jī)配置和用戶配置前面都有個紅叉,右鍵-屬性-錯誤信息里面顯示:
    Title
    由于下面列出的錯誤,組策略結(jié)構(gòu) 失敗。

    系統(tǒng)找不到指定的路徑。

    注意: 由于 GP Core 失敗,其它組策略組件沒有一個處理了它們的策略。因此,其它組件的狀態(tài)信息不可用。
    好像是有某個組策略找不到,所以不能應(yīng)用的意思。
    然后想起來在域名下面有個“新建組策略”,但是沒有做過任何配置,應(yīng)該是有人手賤點(diǎn)了一下新建按鈕加進(jìn)去的,于是把它刪除,還是不行。
    重啟了一下客戶端,居然好了,時間也可以改了,屏幕保護(hù)也可以改了,一切都按計劃進(jìn)行。


    莫名其妙~~
    posted @ 2014-06-23 16:11 amp@java 閱讀(1347) | 評論 (0)編輯 收藏

    現(xiàn)在的手機(jī)攝像頭動輒幾百萬上千萬像素,如果電腦需要用到攝像頭又沒有的話,不妨用手機(jī)的攝像頭代替。

    我是在做一個電腦二維碼識別器的時候,因?yàn)樵瓉淼臄z像頭太差,從而想到用一臺淘汰的Android手機(jī)來代替。

    這類應(yīng)用應(yīng)該不少,我首先找到的是一個叫DraoidCam的應(yīng)用,裝好之后發(fā)現(xiàn)免費(fèi)版沒法調(diào)整分辨率,于是放棄之。

    然后又找到了一個國內(nèi)做的免費(fèi)軟件,叫魅色,非常簡單,支持USB和WiFi連接方式,如果是USB連接的話,打開USB調(diào)試模式之后,運(yùn)行電腦的客戶端,手機(jī)上就自動裝上了App并且自動運(yùn)行,可以調(diào)整分辨率,不過最高只有640*480,幀率不到10,不過已經(jīng)能夠滿足我的需求了。

    然后就可以像普通PC攝像頭一樣使用了,在JMF里面也能找到,于是就可以被Java調(diào)用了。經(jīng)測試,效果比原來的PC攝像頭好多了。

    軟件主頁:http://www.libfetion.org/meise/
    posted @ 2014-06-05 15:35 amp@java 閱讀(1723) | 評論 (4)編輯 收藏

         摘要: TabActivity在API 13(Android 3.2)被標(biāo)記為過期,需要使用Fragment來實(shí)現(xiàn),F(xiàn)ragment是Android 3.0引入的一個概念,主要就是為了適應(yīng)各種不同的屏幕大小(手機(jī)、平板電腦)。Android 4.1發(fā)布時,google還發(fā)布了一個Android Support v4的包,用于Android 1.6以上的系統(tǒng)兼容新的特性,其中包括Fragment。為了在低于...  閱讀全文
    posted @ 2012-12-27 19:07 amp@java 閱讀(15645) | 評論 (0)編輯 收藏

    SQL Server 2000的導(dǎo)入導(dǎo)出功能還是不錯的,支持各種各樣的數(shù)據(jù)庫,但是卻有好多奇怪的bug,不能直接操作,幾乎每一步都要上網(wǎng)搜索,最后搞定了,一定要記下來:
    1、在同一臺電腦上裝好SQL Server 2000的客戶端和Oracle 10g的客戶端,并分別設(shè)置好到源數(shù)據(jù)庫(SQL Server 2000數(shù)據(jù)庫)和目標(biāo)數(shù)據(jù)庫(Oracle 數(shù)據(jù)庫)的連接,兩個數(shù)據(jù)庫都有圖形界面的企業(yè)管理器,很容易設(shè)置好;
    2、在控制面板-管理工具-數(shù)據(jù)源里添加一個DSN,驅(qū)動程序選擇類似“Oracle in OraClient10g_home1”的,確定之后輸入Data Source Name(隨意),Description(隨意),TNS Service Name(在企業(yè)管理器里設(shè)置好的連接名),User ID(用戶名),然后按Test Connection測試是否連接成功,成功之后點(diǎn)OK;
    3、在SQL Server 2000的企業(yè)管理器里,在任意一個表上點(diǎn)右鍵,所有任務(wù),導(dǎo)出數(shù)據(jù),在目的里選擇“Oracle in OraClient10g_home1”,用戶/系統(tǒng)DSN里面就會出現(xiàn)剛才設(shè)置好的DSN名字,選中,然后輸入用戶名密碼,點(diǎn)兩次下一步就會出現(xiàn)選擇源表和視圖對話框
    4、這里要注意的是,勾上源中的某個表,在目的里面就會出現(xiàn)"用戶名"."表名"的默認(rèn)選項(xiàng),如果你剛才使用的Oracle用戶名是小寫的話,這里也會是小寫,一定要改成大寫,否則會提示該用戶名不存在

    目的也可以使用Microsoft OLE DB Provider for Oracle,在屬性里面設(shè)置服務(wù)器名稱為Oracle的TNS名稱,用戶名和密碼輸入Oracle用戶名和密碼,測試連接通過即可,后面的步驟都一樣。

    如果出現(xiàn)以下錯誤:

    OLE DB 提供程序 'MSDAORA' 報錯。

    [OLE/DB provider returned message: 未找到 Oracle 客戶端和網(wǎng)絡(luò)組件。這些組件是由 Oracle 公司提供的,是 Oracle 8i (或更高) 客戶軟件安裝的一部分。

     

    在安裝這些組件之前,將無法使用此提供程序。]

    OLE DB 錯誤跟蹤[OLE/DB Provider 'MSDAORA' IDBInitialize::Initialize returned 0x80004005:  


    就要修改注冊表,有人已經(jīng)作出了詳細(xì)的修改說明,在這里可以看到:
    http://www.cnblogs.com/autumn/articles/splinkedserver.html

    我把那個表也貼在這里:
    Oracle Client  Microsoft Windows NT、
    Oracle Microsoft Windows 95、
    Client Windows 98 和 Windows 98 SE
    Microsoft Windows 2000/XP/2003
    7.x [HKEY_LOCAL_MACHINE\SOFTWARE
    \Microsoft\TransactionServer\Local Computer\My Computer]
    "OracleXaLib"="xa73.dll"
    "OracleSqlLib"="SQLLib18.dll"
    "OracleOciLib"="ociw32.dll

     

    [HKEY_LOCAL_MACHINE\SOFTWARE
    Microsoft\MSDTC\MTxOCI]
    "OracleXaLib"="xa73.dll"
     "OracleSqlLib"="SQLLib18.dll"
     "OracleOciLib"="ociw32.dll"
     
    8.0 [HKEY_LOCAL_MACHINE\SOFTWARE
    \Microsoft\Transaction Server
    \Local Computer\My Computer]
    "OracleXaLib"="xa80.dll"
    "OracleSqlLib"="sqllib80.dll"
    "OracleOciLib"="oci.dll"
     
    [HKEY_LOCAL_MACHINE\SOFTWARE
     \Microsoft\MSDTC\MTxOCI]
     "OracleXaLib"="xa80.dll"
     "OracleSqlLib"="sqllib80.dll"
    "OracleOciLib"="oci.dll"
    8.1 [HKEY_LOCAL_MACHINE\SOFTWARE
    \Microsoft\Transaction Server
    \Local Computer\My Computer]
    "OracleXaLib"="oraclient8.dll"
    "OracleSqlLib"="orasql8.dll"
    "OracleOciLib"="oci.dll"
     
    [HKEY_LOCAL_MACHINE\SOFTWARE
     \Microsoft\MSDTC\MTxOCI]
    "OracleXaLib"="oraclient8.dll"
    "OracleSqlLib"="orasql8.dll"
    "OracleOciLib"="oci.dll"
     
    9.0 [HKEY_LOCAL_MACHINE\SOFTWARE
    \Microsoft\Transaction Server
    \Local Computer\My Computer]
    "OracleXaLib"="oraclient9.dll"
    "OracleSqlLib"="orasql9.dll"
    "OracleOciLib"="oci.dll"
    [HKEY_LOCAL_MACHINE\SOFTWARE
     \Microsoft\MSDTC\MTxOCI]
    "OracleXaLib"="oraclient9.dll"
    "OracleSqlLib"="orasql9.dll"
    "OracleOciLib"="oci.dll"
     
    10.0 [HKEY_LOCAL_MACHINE\SOFTWARE
    \Microsoft\Transaction Server
    \Local Computer\My Computer]
    "OracleXaLib"="oraclient10.dll"
    "OracleSqlLib"="orasql10.dll"
    "OracleOciLib"="oci.dll"
    [HKEY_LOCAL_MACHINE\SOFTWARE
     \Microsoft\MSDTC\MTxOCI]
    "OracleXaLib"="oraclient10.dll"
    "OracleSqlLib"="orasql10.dll"
    "OracleOciLib"="oci.dll"
     
    posted @ 2012-04-28 10:22 amp@java 閱讀(2565) | 評論 (0)編輯 收藏

    當(dāng)讀寫二進(jìn)制文件,或者要把非標(biāo)準(zhǔn)長度的整數(shù)與標(biāo)準(zhǔn)長度的整數(shù)互相轉(zhuǎn)換時,就要用到大量的位操作,雖然看起來很簡單,實(shí)際上里面卻有很多細(xì)節(jié)很容易出錯。

    首先,Java有些標(biāo)準(zhǔn)跟C/C++是不同的:

    1、Java采用高字節(jié)在前的方式讀寫數(shù)據(jù),例如要把一個4字節(jié)的int數(shù)值寫入文件時,它是按照從高字節(jié)到低字節(jié)的順序?qū)懭氲模x取的時候也是這樣讀出來。
    而C/C++則采用平臺相關(guān)的方式,在Windows平臺采用低字節(jié)在前的方式,在Linux/Unix平臺則采用高字節(jié)在前的方式。
    如果Java要讀取C/C++創(chuàng)建的二進(jìn)制文件,就要注意這個問題,最好先搞清楚原來的文件是采用哪種方式創(chuàng)建的。網(wǎng)絡(luò)通信也要注意。

    2、Java沒有無符號數(shù),無論byte,short,int,long都是有符號整數(shù),而C/C++有個unsigned關(guān)鍵字可以設(shè)置一個數(shù)值為無符號數(shù)。

    3、Java的整數(shù)基本數(shù)據(jù)類型就是byte,short,int,long這幾個,長度分別為1,2,4,8字節(jié),C/C++可以用typedef定義各種數(shù)據(jù)類型。

    第二,Java是采用補(bǔ)碼來存放整數(shù)的。
    有時候覺得補(bǔ)碼的定義有些奇怪,實(shí)際上可以這樣理解:

    把一個整數(shù)從0一直往上加1,加到溢出就變成了負(fù)數(shù)的最小值,然后再繼續(xù)加1,最后又能回到0,實(shí)際上就是一個輪回。
    例如一個byte類型的整數(shù),一共有8位,能表示256個數(shù)值,采用補(bǔ)碼的話數(shù)值范圍就是-128~127,表示方法如下:
    0        0000 0000
    1        0000 0001
    .
    .
    126    0111 1110
    127    0111 1111
    -128   1000 0000
    -127   1000 0001
    .
    .
    -1       1111 1111
    0         0000 0000

    第三、不同長度的整數(shù)轉(zhuǎn)換。
    如果是從較短的數(shù)轉(zhuǎn)成較長的數(shù),很簡單,如果是正數(shù)就在高字節(jié)補(bǔ)0,如果是負(fù)數(shù)就在高字節(jié)補(bǔ)1。
    例如byte的127轉(zhuǎn)為short的127:
    byte:0111 1111
    short:0000 0000 0111 0111
    byte的-127轉(zhuǎn)為short的-127
    byte:1000 0001
    short:1111 1111 1000 0001
    如果是從較長的數(shù)轉(zhuǎn)成較短的數(shù),實(shí)際上就是把高位都截斷了,所以轉(zhuǎn)出來的數(shù)值可能完全不是一回事了。
    例如short的256轉(zhuǎn)為byte:
    short:0000 0001 0000 0000
    byte: 0000 0000
    把256變成了0
    short的-255轉(zhuǎn)成byte:
    short:1111 1111 0000 0001
    byte:0000 0001
    把-255變成了1

    第四、位運(yùn)算操作符及它們的優(yōu)先級
    Java的位運(yùn)算操作符包括:~非,|按位或,&按位與,^按位異或,<<左移,>>右移,>>>右移左側(cè)補(bǔ)0
    各種運(yùn)算符的優(yōu)先級如下表所示:
    優(yōu)先級
    運(yùn)算符
    結(jié)合性
    1
    () [] .
    從左到右
    2
    ! +(正) -(負(fù)) ~ ++ --
    從右向左
    3
    * / %
    從左向右
    4
    +(加) -(減)
    從左向右
    5
    << >> >>>
    從左向右
    6
    < <= > >= instanceof
    從左向右
    7
    == !=
    從左向右
    8
    &(按位與)
    從左向右
    9
    ^
    從左向右
    10
    |
    從左向右
    11
    &&
    從左向右
    12
    ||
    從左向右
    13
    ?:
    從右向左
    14
    = += -= *= /= %= &= |= ^= ~= <<= >>= >>>=
    從右向左
    根據(jù)該表可以看到,位運(yùn)算操作符的優(yōu)先級各有不同,分別為:
    1、~
    2、>> << >>>
    3、&
    4、^
    5、|
    另外需要特別注意的是,除了~,其他位運(yùn)算操作的優(yōu)先級都低于加減,所以要記得以下語句是返回32而不是7!
    1<<2+3
    還有就是&、^、|的優(yōu)先級都是低于邏輯操作符的,因此下面的語句會編譯出錯,幸好Java不像C那樣對所有大于1的值都認(rèn)為是真,否則下面的語句也能編譯通過,但可能與你的意圖不太一樣,可能調(diào)試半天才發(fā)現(xiàn)。
    if(3&1>0)
    如果記不清楚,還是按照你的意圖加上括號最保險。

    第五、字節(jié)數(shù)組與整數(shù)之間的轉(zhuǎn)換
    為了把一個整數(shù)存入文件,或者從文件中讀取一個整數(shù),需要經(jīng)常在字節(jié)數(shù)組和整數(shù)之間轉(zhuǎn)換,這個過程要用到大量的位運(yùn)算。
    首先需要記住的是,在參與所有運(yùn)算前,Java都會把byte、short類型的值都轉(zhuǎn)換成int,然后再對轉(zhuǎn)換后的int進(jìn)行操作。例如下面的語句會編譯出錯:
    byte a=10,b=20,c;
    c=a+b;

    因?yàn)閍和b在相加前都被轉(zhuǎn)成了int,最后得到的結(jié)果是個int類型的值,如果要賦給byte類型的c,必須顯式地進(jìn)行類型轉(zhuǎn)換,即把第二句改為:
    c=(byte)(a+b)

    這一點(diǎn)很關(guān)鍵,因?yàn)閷τ谝粋€最高位為1的byte類型的整數(shù)(負(fù)數(shù)),在運(yùn)算之前它會被強(qiáng)制轉(zhuǎn)換成int類型,根據(jù)上面所說的第三點(diǎn),其實(shí)就是往前面的三個高字節(jié)補(bǔ)上1,這樣一來,它在參與位運(yùn)算的過程中,就不僅僅是它本身的8個bit參與了,實(shí)際上連前3個字節(jié)的24個bit(均為1)也參與了。例如有一個整數(shù)i=1082163328,它的二進(jìn)制表示為:
    01000000 10000000 10000000 10000000
    分為4個字節(jié)存儲,除了第一個字節(jié)是正數(shù)外,其余3個字節(jié)均為負(fù)數(shù)。假如用a代表最高字節(jié)的值,用b代表其他三個字節(jié)的值,如果按照通常的理解,你可能會這樣得到i的值:
    i=(a<<24)+(b<<16)+(b<<8)+b

    如果a和b都是正數(shù),上面的等式是成立的,但是在這個例子里,卻是錯的,因?yàn)樯鲜街械腶和b都已經(jīng)被強(qiáng)制轉(zhuǎn)換成了int類型再參加運(yùn)算,實(shí)際上
    a=00000000 00000000 00000000 01000000
    b=11111111 11111111 11111111 10000000
    i=01000000 00000000 00000000 00000000+11111111 10000000 00000000 00000000+11111111 11111111 10000000 00000000+11111111 11111111 11111111 10000000
    最后得到的結(jié)果是1065320320,不是原來的值了。
    為了不讓byte在強(qiáng)制轉(zhuǎn)換成int的過程加入了我們不想要的高位1,我們需要把它跟0xff進(jìn)行與操作,i的值應(yīng)該這樣運(yùn)算:
    = ( ( a& 0xff ) << 24 ) +( ( b & 0xff ) << 16 ) + ( ( b & 0xff ) << 8 ) + ( b & 0xff )

    注意,因?yàn)?amp;和<<的優(yōu)先級都低于+,所以上面的括號是不能少的。不過由于跟0xff與操作之后,其余24位都變成了0,因此可以把+改為|操作,因?yàn)槿魏沃蹬c0進(jìn)行或操作都得到本身:
    = ( a & 0xff ) << 24 | ( b & 0xff ) << 16 | ( b & 0xff ) << 8 | ( b & 0xff )

    由于<<的優(yōu)先級高于|,所以省了一些括號。最高字節(jié)可以不與0xff進(jìn)行與操作,因?yàn)樗D(zhuǎn)換成int后左邊增加的3個字節(jié)都在左移24位時被去掉了:
    = a << 24 | ( b & 0xff ) << 16 | ( b & 0xff ) << 8 | ( b & 0xff )


    把int轉(zhuǎn)為字節(jié)數(shù)組的時候比較簡單,直接右移截斷即可:
    byte[] b = new byte[4];
    b[0= (byte) (i >> 24);
    b[1= (byte) (i >> 16);
    b[2= (byte) (i >> 8);
    b[3= (byte) i;


    第六、非標(biāo)準(zhǔn)長度整數(shù)的存儲和讀取
    假如有兩個變量,他們的值可以用12個bit來表示,如果我們用16bit的short類型來表示一個變量,那么兩個變量就需要4個字節(jié),而實(shí)際上它們只需要3個字節(jié)就能表示出來,如果存儲空間比較有限,寫入文件時可以把它們存放在3個字節(jié)里面,但是讀寫過程就需要進(jìn)行轉(zhuǎn)換。
    在內(nèi)存里,它們都是標(biāo)準(zhǔn)的數(shù)據(jù)類型:
    short a,b;

    寫入文件時,我們用第一個字節(jié)和第二個字節(jié)的前半部分來表示a,把第二個字節(jié)的后半部分和第三個字節(jié)來表示b,即:
    1:xxxx xxxx
    2:xxxx yyyy
    3:yyyy yyyy
    x和y都表示一個bit,分別用來存放a和b。寫入時先把a(bǔ)和b轉(zhuǎn)為字節(jié)數(shù)組:
    byte[] out = new byte[3];
    out[
    0= (byte) ( a >> 4 );//把a(bǔ)的高8位放在第一個字節(jié)
    out[1= (byte) ( a << 4 );//先把a(bǔ)左移四位,在右邊補(bǔ)上4個0,第二個字節(jié)的高4位就是a的低4位了,第二個字節(jié)的高4位已經(jīng)生成,低4位還是0
    out[1|= (byte) ( b >> 8 & 0x0f );//b右移8位,并與0x0f進(jìn)行與操作,實(shí)際上就只保留了b的高4位,并且是在字節(jié)的低4位上,跟第二步得到的字節(jié)進(jìn)行或操作,就生成了第二個字節(jié)
    out[2= (byte) b;//把b的高4位截斷就得到了低8位
    然后再把這個字節(jié)數(shù)組寫入文件,就可以用3個字節(jié)表示兩個整數(shù)了。
    讀取:
    =(short)( (out[0& 0xff<< 4 | ( out[1& 0xf0 )>>4);
    = (short)((out[1& 0x0f<< 8 | ( out[2& 0xff));
    posted @ 2012-04-08 16:56 amp@java 閱讀(1841) | 評論 (2)編輯 收藏

    AdMob是往手機(jī)應(yīng)用程序里添加廣告的最流行的方式,Android程序基本都是靠這個賺錢。看文檔似乎很簡單,但是操作起來卻不是那么回事,今天搞了一上午才弄明白怎么正確添加,網(wǎng)上搜索到的資料都不適合最新的SDK。

    按照AdMob的官方文檔,很簡單,只要把AdMob的開發(fā)包jar放到Build Path的Libraries里面就行了,這樣做編譯是沒問題的,但是一運(yùn)行就會出錯,提示
    java.lang.NoClassDefFoundError:com.google.ads.AdView
    這是因?yàn)镚oogle最近更新了ADT到17.0,改變了項(xiàng)目依賴的檢測方式,官方的說明在這里,不過看得不是很懂。有人用圖形的方式標(biāo)了出來,容易理解一些,看這里。如果不求甚解,就把剛才放到Build Path里面的jar移除,直接在項(xiàng)目目錄下建立一個libs目錄,然后把那個jar文件放進(jìn)去就行了。

    AdMob SDK也更新到了4.3.1,網(wǎng)上搜索到的在XML文件里面設(shè)置AdView屬性的方法也已過時,現(xiàn)在不需要建立attrs.xml文件,直接增加一個
    xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
    就可以在AdView標(biāo)簽里面設(shè)置ads開頭的屬性了,關(guān)于xml設(shè)置AdView屬性的官方文檔隱藏得比較深,沒有在目錄中列出來,只能在其他文檔里面的鏈接里進(jìn)去,在這里
    另外,按照官方說明,要在AndroidManifest.xml里面添加一個Activity的聲明:
        <activity android:name="com.google.ads.AdActivity"
                  android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
    后面那個屬性android:configChanges的最后兩個值screenSize|smallestScreenSize是在Android 3.2后面才增加的,這兩個值必須填上去,否則運(yùn)行的時候會報錯。如果你使用的SDK是3.2以下的,識別不了這兩個值,編譯也不會報錯。因此你的項(xiàng)目必須使用Android 3.2以上的SDK,也就是項(xiàng)目根目錄下的project.properties文件里面的屬性target的值必須是android-13以上,例如
    target=android-15
    但是可以在AndroidManifest.xml里面設(shè)置android:minSdkVersion和android:targetSdkVersion為比13低的值,這樣就不需要安裝Android 3.2以上的手機(jī)或平板來運(yùn)行這個程序,實(shí)際上AdMob支持Android 1.5以上的系統(tǒng),只是開發(fā)需要更高版本的SDK而已。


    這次折騰讓我真正體會到Android更新得實(shí)在太快了,連官方的文檔都來不及更新,開發(fā)人員只能自己摸索總結(jié),幸好有強(qiáng)大的搜索工具,只要你遇到的問題不是第一個,就會有人找到解決方案。



    posted @ 2012-03-25 19:23 amp@java 閱讀(3705) | 評論 (7)編輯 收藏

    SWT里TableEditor的作用是可以在表格里面顯示一些控件,例如列表、按鈕等,有時候是根據(jù)表格的內(nèi)容在控件上顯示不同內(nèi)容的,如果更新了表格內(nèi)容,就要同時更新控件,但是表格內(nèi)容可以通過Table控件的removeAll()來清除,而表格中的控件則無法用這個方法清除,你調(diào)用Table的removeAll()方法,往表格里填入新內(nèi)容后,控件還是上次的控件,但是你一操作那些控件就會出異常,提示那些控件已經(jīng)disposed。

    解決方法是顯式地調(diào)用控件及TableEditor的dispose()方法,在你建立TableEditor的時候,把它的引用保存起來,把里面的控件的引用也保存起來,到整個表格需要的清除的時候,通過引用先把控件dispose掉,再把TableEditor也dispose掉,這樣整個表格的內(nèi)容就真正清除了。

    例如有一個表格名為table,里面的每一行都有3列,第一列是文本,第二列是Combo,第三列是Button,繪制表格的時候是這樣的:

    TableItem ti = new TableItem(table,SWT.NONE);
    ti.setText(
    0,"some string");
    te 
    = new TableEditor(table);
    Combo combo 
    = new Combo(table,SWT.NONE);
    controls.add(combo);
    te.setEditor(combo,ti,
    1);
    Button button 
    = new Button(table,SWT.NONE);
    controls.add(button);
    te.setEditor(button,ti,
    2);

    其中te和controls都是成員變量,te的類型是TableEditor,controls的類型是ArrayList<Control>。
    當(dāng)整個table要清除內(nèi)容時,可以這樣:
    //刪除控件
    for(Control control:controls){
    control.dispose();
    }
    //刪除TableEditor
    te.dispose();
    //刪除文本
    table.removeAll();
    posted @ 2012-03-09 11:09 amp@java 閱讀(3850) | 評論 (0)編輯 收藏

    mars課程里關(guān)于Socket通信那一課說那些程序只能在真機(jī)上運(yùn)行,模擬器模擬不了,實(shí)際上是可以的。
    Android模擬器是通過一個類似路由器的虛擬網(wǎng)絡(luò)層與電腦相連,可以看作模擬器是處于“內(nèi)網(wǎng)”當(dāng)中,每個模擬器都有自己的虛擬路由器,而且虛擬路由器的地址總是10.0.2.1,在模擬器看來,電腦的地址是10.0.2.2,模擬器自己的地址是10.0.2.15,無論你啟動多少個模擬器,對于模擬器來說都是這樣的地址,模擬器之間不能直接通信。
    啟動模擬器的時候,電腦會給模擬器分配兩個端口,通過這兩個端口,電腦就能操作模擬器。第一個啟動的模擬器的端口是5554和5555,第二個是5556和5557,以此類推,最多可以同時啟動32個模擬器。第一個端口(偶數(shù)端口)可以接受telnet連接,對模擬器進(jìn)行設(shè)置,第二個端口(奇數(shù)端口)則接受adb連接,可以用來調(diào)試。第一個端口可以在模擬器窗口的標(biāo)題欄看到,如下圖所示:

    5554表示端口號,t表示模擬器名稱。
    實(shí)際上,這些端口也是電腦監(jiān)聽的端口,在電腦上通過netstat可以看到本機(jī)正在監(jiān)聽這些端口,因此通過telnet localhost 5554就能連上第一臺模擬器,連上之后通過help命令可以查看操作幫助。
    為了實(shí)現(xiàn)電腦和模擬器上的android程序進(jìn)行socket通信,需要把程序開啟的端口通過端口映射設(shè)置到電腦上,這跟家里的路由器端口映射概念是一樣的。telnet到模擬器之后,通過
    redir add tcp:1234:1234
    就能把模擬器上的1234端口映射到電腦上,第一個表示電腦端口,第二個表示模擬器程序要使用端口,這兩個數(shù)字可以相同也可以不同,要映射udp端口就把tcp改為udp即可
    redir add udp:1234:1234
    這樣一來,當(dāng)模擬器的程序打開1234端口時,在電腦上也打開了對應(yīng)的端口,只要通過電腦連接127.0.0.1的對應(yīng)端口,就連上了模擬器的程序端口,就可以通過電腦上的client向模擬器的server發(fā)送數(shù)據(jù),不需要通過真機(jī)運(yùn)行。
    如果要讓第一個模擬器向第二個模擬器發(fā)送數(shù)據(jù),也可以把第二個模擬器的端口映射到電腦上,然后在第一個模擬器程序中向10.0.2.2的對應(yīng)端口發(fā)送數(shù)據(jù)即可。


    模擬器還有一個很有意思的功能,每個模擬器默認(rèn)的電話號碼就是它的第一個端口號,例如開了兩個模擬器,第一個撥打5556,第二個就會顯示5554來電,還能接通,發(fā)短信也可以,這樣就能模擬電話和短信功能。

    詳細(xì)的信息可以看Dev Guide的模擬器部分:http://developer.android.com/guide/developing/devices/emulator.html
    posted @ 2012-02-24 10:37 amp@java 閱讀(2414) | 評論 (0)編輯 收藏

    前天是情人節(jié),雖然結(jié)婚好多年了,但是老婆一直都喜歡驚喜的浪漫,可惜我卻是個木訥的呆子,做不出那些轟動的事情。那天下午馬上就要下班回家了,突然在微博上看到有人談到geek的情人節(jié)禮物,雖然我不是geek,但是最近在學(xué)Android,老婆的手機(jī)也是Android系統(tǒng)的,何不專門做個程序給她?

    想法可嘉,但是動起手來卻不是那么回事。學(xué)了那么多天,真正派上用場的還沒學(xué)到。時間只剩下不到一個小時了,我會的只是在屏幕上顯示幾個大字:XXX,我愛你!

    后來想想似乎太單調(diào),如果能夠加上點(diǎn)背景音樂可能好點(diǎn),但是還沒學(xué)會怎么使用,上網(wǎng)搜了一下,幸好很簡單,用MediaPlayer就可以了,幾條語句就能搞定。音樂文件怎么來呢?通過網(wǎng)絡(luò)在線播放是最簡單的,于是就到百度MP3搜了一下“情人節(jié)快樂”,我記得有一首歌里面一直在喊“情人節(jié)快樂”的,結(jié)果最后發(fā)現(xiàn)那首歌名字叫《沒有情人的情人節(jié)》……

    算了,管它呢,有老婆就行了,沒有情人照樣過情人節(jié),打開發(fā)現(xiàn)鏈接居然是百度的,以前百度不是說它只負(fù)責(zé)搜索,不負(fù)責(zé)存放嗎,怎么現(xiàn)在的MP3都放在百度的服務(wù)器了?把鏈接復(fù)制下來,在模擬器上運(yùn)行還是挺好的,因?yàn)樗玫氖请娔X的寬帶,呵呵。不過過了一會提示下載失敗,把那個地址往瀏覽器一貼,果然打不開了,原來百度這種下載鏈接是有有效期的,只能讓你試聽一下,然后下載,不是長期有效的。這就麻煩了,到時候裝在手機(jī)上沒聲音豈不是很糗?

    再搜索一下,還好,可以把MP3文件放在assets里面,發(fā)布程序的時候把它包含在apk里面就行了,不用聯(lián)網(wǎng)了。

    現(xiàn)在可以在顯示大字的同時播放《沒有情人的情人節(jié)》了。看了一下效果,還是有點(diǎn)怪異,手機(jī)的狀態(tài)欄和程序的標(biāo)題跟黑色的背景,紅色的大字似乎不太搭配,于是繼續(xù)搜索全屏代碼,哈哈,兩句搞定,這樣炫多了。

    不過一直看著那幾個字沒任何反應(yīng),似乎太單調(diào)了,于是就想讓它們不斷變色,或者動一下也好,但是無論怎么弄都搞不定,下班時間到了,要去接老婆了,就這樣吧。

    之前都是在模擬器上運(yùn)行,或者接個USB在手機(jī)上運(yùn)行,還不知道怎么打包成apk呢,這下居然沒搜索到,可能太簡單了,大家都沒說。于是在項(xiàng)目上點(diǎn)右鍵,果然看到導(dǎo)出apk的菜單,我選擇了unsigned方式導(dǎo)出,在手機(jī)上居然安裝不了。再搜索一下,哦,原來是要導(dǎo)出成signed apk才能裝的,但是我沒有證書,怎么signed呢?沒想到ADT還可以生成證書,一下就搞定了,這比Symbian那種簽名簡單多了,但是可能也是導(dǎo)致Android惡意軟件泛濫的原因之一。

    去接老婆的時候通過藍(lán)牙把a(bǔ)pk發(fā)到她手機(jī)上,裝上,運(yùn)行,從她表情上看出,我的努力沒有白費(fèi)。不過最后還是發(fā)現(xiàn)了個嚴(yán)重的bug,那首歌還沒放完,另外一個聲音已經(jīng)重新開始了,形成了“二重唱”的效果,而且程序退出之后還在唱,趕工造成的悲劇啊。

    下面是代碼:
    public class LoveActivity extends Activity {
        TextView text;
        
    /** Called when the activity is first created. */
        @Override
        
    public void onCreate(Bundle savedInstanceState) {
            
    super.onCreate(savedInstanceState);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,   
            WindowManager.LayoutParams.FLAG_FULLSCREEN);  
            requestWindowFeature(Window.FEATURE_NO_TITLE);  
            setContentView(R.layout.main); 
            MediaPlayer mp 
    = new MediaPlayer();
            
    try{
                AssetManager assetManager 
    = getAssets();
                AssetFileDescriptor afd 
    = assetManager.openFd("a.mp3");
                mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                mp.prepare();
                mp.start();
            }
            
    catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    main.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation
    ="vertical"
        android:layout_width
    ="fill_parent"
        android:layout_height
    ="fill_parent"
        
    >
        
    <TextView 
        
    android:id="@+id/textView1" 
        android:text
    ="@string/loveyou" 
        android:layout_width
    ="match_parent" 
        android:layout_height
    ="match_parent" 
        android:gravity
    ="center" 
        android:textColor
    ="#ff0000"
        android:textStyle
    ="bold"
        android:textSize
    ="50dip"
        
    />
        
       
    </LinearLayout>
    strings.xml:
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        
    <string name="hello">Hello World, LoveActivity!</string>
        
    <string name="app_name">Love</string>
        
    <string name="loveyou">XXX\n我愛你</string>
    </resources>
    再把那首mp3放到assets里,改名為a.mp3即可。




    希望明年能做出個更好的。
    posted @ 2012-02-16 11:06 amp@java 閱讀(2295) | 評論 (2)編輯 收藏

    昨天在調(diào)試一段Android程序的時候發(fā)現(xiàn)總是出現(xiàn)NullPointerException,是來自一句System.out.println(),但是把里面的內(nèi)容分拆了幾次都找不到哪里有null,最后發(fā)現(xiàn)居然是因?yàn)樽罱K輸出的字符串是null!

    一直以來,在JavaSE里,如果字符串本身是null,System.out.println()打印該字符串,會在終端輸出“null”,而在Android里卻是直接拋出NullPointerException,整個程序都會被終止。

    大家可以測試一下下面的語句在兩種環(huán)境下的運(yùn)行結(jié)果:
    1 String s = null;
    2 System.out.println(s);
    posted @ 2012-02-13 14:49 amp@java 閱讀(1378) | 評論 (1)編輯 收藏

    這是mars課程里面關(guān)于handler和線程的一個例子:
    package mars.handler;

    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;

    public class HandlerTest extends Activity {
        Handler handler 
    = new Handler();
        
    /** Called when the activity is first created. */
        @Override
        
    public void onCreate(Bundle savedInstanceState) {
            
    super.onCreate(savedInstanceState);
            System.out.println(
    "1");
            handler.post(r);
            System.out.println(
    "2");
            setContentView(R.layout.main);
            System.out.println(
    "activity---->"+Thread.currentThread().getId());
            System.out.println(
    "activity name--->"+Thread.currentThread().getName());
        }
        
        Runnable r 
    = new Runnable() {
            
            @Override
            
    public void run() {
                
    // TODO Auto-generated method stub
                System.out.println("handler---->"+Thread.currentThread().getId());
                System.out.println(
    "handlername---->"+Thread.currentThread().getName());
                
    try {
                    Thread.sleep(
    10000);
                } 
    catch (InterruptedException e) {
                    
    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println(
    "3");
            }
        };
    }

    根據(jù)mars的解釋,handler所在的線程跟Activity的線程是同一個線程,所以在
    handler.post(r);
    語句后,執(zhí)行的是Runnable里面的run函數(shù),這個函數(shù)沒有在新開的線程中執(zhí)行,只是簡單地調(diào)用了run函數(shù),所以這個app在模擬器運(yùn)行時要過10秒才會顯示界面,因?yàn)閞un函數(shù)里面睡眠了10秒,等它返回后才執(zhí)行setContentView函數(shù)設(shè)置界面元素。
    根據(jù)實(shí)際運(yùn)行結(jié)果,的確是過了10秒才能顯示界面。

    但是奇怪的是System.out語句似乎沒有受到影響,下面是日志:
    log
    02-09 11:12:43.553: INFO/System.out(591): 1
    02-09 11:12:43.553: INFO/System.out(591): 2
    02-09 11:12:43.674: INFO/System.out(591): activity---->1
    02-09 11:12:43.674: INFO/System.out(591): activity name--->main
    02-09 11:12:43.713: INFO/System.out(591): handler---->1
    02-09 11:12:43.713: INFO/System.out(591): handlername---->main
    02-09 11:12:53.775: INFO/System.out(591): 3

    從日志可以看出,除了run函數(shù)里面睡眠后才執(zhí)行的打印函數(shù)推遲了10秒才執(zhí)行之外,其他都是沒有受到任何延時,順序執(zhí)行的,在
    handler.post(r);
    語句前后的打印函數(shù)都被按順序執(zhí)行了,唯獨(dú)
    setContentView(R.layout.main);
    需要在run函數(shù)返回后才執(zhí)行,這是什么道理?難道打印函數(shù)的優(yōu)先級更高,不會堵塞?如果是這樣的話為什么在run函數(shù)里面還是要等睡眠結(jié)束才執(zhí)行呢?
    posted @ 2012-02-09 19:25 amp@java 閱讀(1837) | 評論 (6)編輯 收藏

    很想搞點(diǎn)Android的小程序玩玩,但是卻萬事開頭難,不知道從哪里開始,看了官方的文檔,結(jié)果一天都看不了幾段,還是英文的,比較痛苦。找了些電子書,也是看過目錄就不知道放哪里了。這種編程的入門沒有強(qiáng)大的決心真的很難靜下心來學(xué)習(xí)。
    前幾天又心血來潮,搜索了一下android開發(fā)的網(wǎng)站,發(fā)現(xiàn)了一些視頻,看起來還挺有意思,連續(xù)看了幾個,慢慢地也摸著一點(diǎn)門路了,以前沒有試過用這種方法學(xué)習(xí),都是看書,現(xiàn)在發(fā)現(xiàn)看視頻似乎更高效,起碼眼睛沒那么累,有人在念,很多時候只要用耳朵聽就行了,而且所有軟件的界面、步驟都很清楚,這些東西通過書是沒法表現(xiàn)出來的。
    現(xiàn)在學(xué)會了讓一個Activity顯示出來,放上點(diǎn)控件,處理一下點(diǎn)擊,頁面布局等,算是入門了,但很多東西還要繼續(xù)看,那些視頻還有好多。
    入門系列視頻地址:
    http://www.marsdroid.org/
    還有一個深入淺出系列:
    http://www.eoeandroid.com/thread-109361-1-1.html
    由于沒有入門,所以還在看第一個系列,第二個系列只看了兩個。
    到現(xiàn)在發(fā)現(xiàn)android界面的構(gòu)建很像web界面,android是通過layout來排布控件,而web是通過css,android可以通過java來操縱控件,而web則是通過javascript操縱控件,回調(diào)函數(shù)則跟JavaSE一樣。



    不過有時候很容易忘記了一個步驟導(dǎo)致程序運(yùn)行出錯,一般來說,要讓一個Activity成功運(yùn)行,需要做以下步驟:
    1、有一個繼承與Activity的類
    2、有一個layout文件,里面是各種控件的布局,在Activity里面應(yīng)該用setContentView加載這個layout
    3、有一個strings文件,里面是界面的各種字符串,用于國際化
    4、在AndroidManifest里面加入這個Activity
    第4步很容易忘記。
    posted @ 2012-02-08 14:55 amp@java 閱讀(261) | 評論 (0)編輯 收藏

    前段時間聽了一家公司介紹分布式存儲產(chǎn)品,號稱性能超過傳統(tǒng)的磁盤陣列+小型機(jī),但價格卻比這種組合低,而且具有維護(hù)簡單、數(shù)據(jù)安全等優(yōu)點(diǎn),其核心就是把一些PC服務(wù)器通過網(wǎng)絡(luò)連接起來,把數(shù)據(jù)分散存儲在這些服務(wù)器上,查找的時候把任務(wù)分配到這些服務(wù)器上,讓它們分別完成各自的小任務(wù),最后再匯合出結(jié)果,核心就是:每個節(jié)點(diǎn)都是一個數(shù)據(jù)存儲單元和運(yùn)算單元的結(jié)合,這些節(jié)點(diǎn)性能要求不高,可以是各種各樣的配置,只要在上面運(yùn)行集群要求的軟件即可,一臺掛了不要緊,換上去一臺就能自動恢復(fù),增加一臺就能提高性能,減少一臺也不會有很大影響,只是性能稍微下降,每份數(shù)據(jù)都有多個備份,能夠平衡分布在各服務(wù)器上。這種架構(gòu)的缺點(diǎn)是,只要用上了這套東西,所有的軟件就必須從這家公司購買,因?yàn)檎麄€集群的控制和訪問接口都是他們提供的。
    該公司也坦言這其實(shí)就是google的服務(wù)器應(yīng)用技術(shù),實(shí)際上就是google提出來的云計算。

    今天看了一些文章介紹,發(fā)現(xiàn)上面介紹的東西實(shí)際上已經(jīng)通過Apache的一個項(xiàng)目Hadoop實(shí)現(xiàn),不知道那家公司是不是就是簡單包裝了一下這個項(xiàng)目。

    Hadoop包含兩個主要的模塊,分別是HDFS分布式文件系統(tǒng)和MapReduce集群計算機(jī)制。剛剛發(fā)布了1.0.0版本。

    主頁: http://hadoop.apache.org/

    blogjava有位高手已經(jīng)翻譯了HDFS的架構(gòu)說明:http://m.tkk7.com/killme2008/archive/2008/06/05/206043.html,但對應(yīng)的是上一個版本0.20的,里面說到了很多沒有實(shí)現(xiàn)的東西,不知道是否已經(jīng)在1.0版本實(shí)現(xiàn),目前官方網(wǎng)站上該文章的版本還是0.20的。

    這里有三篇文章介紹Hadoop在單機(jī)環(huán)境、多機(jī)環(huán)境下的安裝和配置,還有應(yīng)用程序的開發(fā):http://www.ibm.com/developerworks/cn/linux/l-hadoop-1/index.html

    看起來還是挺有意思的,以前就曾經(jīng)有過想法,把單位淘汰下來的那一大堆臺式電腦組成一個存儲或者計算的小集群,也許能夠代替一兩臺PC服務(wù)器,現(xiàn)在看來可以試試,以后的趨勢就是云計算了,先自己搞點(diǎn)小云看看效果如何。
    posted @ 2012-01-19 14:47 amp@java 閱讀(224) | 評論 (0)編輯 收藏

    這個不僅僅是IE6的錯,而是所有IE的錯!!
    IE有一個特別隨意的功能,就是能夠通過Element的name來操作一個Element,有些人覺得這個功能很方便,實(shí)際它不僅不符合標(biāo)準(zhǔn),還會導(dǎo)致IE自己變得莫名其妙。
    假如你的Form有一個提交按鈕的name="submit",那么,很遺憾,你這個form無論如何都不能通過Javascript來提交,只要你一調(diào)用了這個form的submit()方法,IE就會告訴你它不支持這個方法!這不是搞笑嗎?哪個瀏覽器會不支持form的submit()方法?雖然IE不標(biāo)準(zhǔn),也不至于這樣吧?對不起,就是這樣。

    因?yàn)楫?dāng)你調(diào)用form的方法submit(),它首先想到的是你的提交按鈕!
    theForm.submit()
    這個語句在IE看來并不是調(diào)用theForm的submit方法,而是調(diào)用了名字為submit的提交按鈕!如果你在某個元素對象后面加個括號,會有什么效果?當(dāng)然就是出錯。在IE的獨(dú)特視角下,上面這個語句與下面這個語句的效果一樣:
    (theForm.submit)();
    前一個括號代表了名稱為submit的按鈕對象,后面那個括號就無法理解了,所以IE告訴你不支持這個方法。

    IE整個家族都是如此的丑陋!

    posted @ 2010-12-09 15:02 amp@java 閱讀(292) | 評論 (0)編輯 收藏

    一直都看到很多人說,IE6是Web開發(fā)人員的惡夢,以前我單位的內(nèi)部網(wǎng)絡(luò),所有電腦裝的都是IE6,我只針對IE6開發(fā),似乎沒什么感覺,反正在我的電腦上看到什么樣的,其他電腦上看到也是一樣的。
    后來因?yàn)槟彻窘o我們做的一個系統(tǒng)運(yùn)行速度實(shí)在太慢,我把自己的電腦更新到IE8,發(fā)現(xiàn)速度快了很多,但是有些東西不兼容,我對那些不兼容的功能使用得比較少,就不管了。
    終于,我自己又要開發(fā)一個小項(xiàng)目,用了一個網(wǎng)上下載的CSS模板,發(fā)現(xiàn)里面很多針對IE的注釋,從IE 5到IE 8都有,反正我電腦上看著效果不錯,于是就用了。
    辛苦了好幾天,我那項(xiàng)目基本完工了,想在IE6上看看效果,Shit,本來顯示在頁面右方主要區(qū)域的表格掉在了左邊導(dǎo)航欄的下面,表格里面一些DIV的下劃線莫名其妙地不見了,這些東西在我的電腦上顯示得好好的,也沒用到什么特別的東西,怎么差別會這么大呢?
    一個個問題排查:
    表格問題,在IE6上表現(xiàn)得有些詭異,顯示完之后表格是在下面的,但是鼠標(biāo)晃過導(dǎo)航欄里面的鏈接,表格又會自動跳到右方區(qū)域,真見鬼。改了一下布局的padding,一個表格好了。另外一個卻還是掉下去,仔細(xì)研究了一下,把表格的寬度減少10px,好了。
    下劃線問題,我用的是:
    border-bottom:1px solid grey
    結(jié)果IE6不會顯示出這條下劃線。搜索一下才知道這是IE6的bug,它理解不了這么長的句子!必須寫成這樣:
    border-bottom-width:1px;
    border-bottom-style:solid;
    border-bottom-color:grey;
    還有比這更傻逼的嗎?有!
    它顯示出的線是黑色的,不是grey的!而且根據(jù)DIV里面內(nèi)容的顏色不同,它還會變色!如果里面是紅色的字,那么它下面的線也是紅色,如果是綠色的字,下面的線也是綠色,如果沒有指定顏色,它就是黑色,非常智能,但就是不顯示你要的顏色!
    后來知道原來它根本不知道grey的意思,必須指定顏色代碼才能解決。


    這就是IE6,沒想到微軟這么大一個公司還出了這么一個垃圾,而且出了那么多年,至今還占據(jù)中國瀏覽器市場的半壁江山!



    posted @ 2010-12-08 20:51 amp@java 閱讀(545) | 評論 (4)編輯 收藏

    有一臺WIN2003的服務(wù)器,在單位的局域網(wǎng)內(nèi),與互聯(lián)網(wǎng)是物理隔離的,最近上面運(yùn)行的一個WEB服務(wù)器經(jīng)常出錯,查看日志發(fā)現(xiàn)是因?yàn)閿?shù)據(jù)庫不能連接,因?yàn)橄到y(tǒng)的所有端口都已經(jīng)被占用完。使用netstat -abn查看發(fā)現(xiàn)svchost.exe開啟了大量狀態(tài)為SYN_SENT的連接,目標(biāo)端口都是445,但是連接的IP各種各樣的都有,由于機(jī)器不能建立Internet連接,所以狀態(tài)都是SYN_SENT,重啟一下這些連接都沒有了,但是過一會又會迅速建立起來,很快就把系統(tǒng)的所有端口都占用了。
    根據(jù)端口找出哪個服務(wù)真不容易,通過netstat -abn只能查到是svchost.exe,最多還能得到一個PID,確定是哪個svchost.exe,然后通過tasklist /svc可以查到那個svchost對應(yīng)了哪些服務(wù),但是一看,很多服務(wù)都是使用那個svchost,包括Server,Workstation等等,根本不知道是哪個產(chǎn)生的連接。
    找了半天發(fā)現(xiàn)有人和我一樣:http://www.petri.co.il/forums/showthread.php?t=36427,討論了半天最后也找到了解決方法:http://www.symantec.com/security_response/writeup.jsp?docid=2009-011316-0247-99,原來是W32.Downadup這個病毒惹的禍,下載了專殺工具回來查了一下,果然找到了兩個被感染的文件,一個是jpg文件,在IE的緩存里,一個是dll文件,在system32里。
    根據(jù)dll文件名在注冊表里查到了它注冊的服務(wù),原來又是之前處理過的那種,服務(wù)名隨機(jī)、服務(wù)描述為空、啟動類型為自動、狀態(tài)為未啟動、dll名隨機(jī),但是我記得這臺服務(wù)器已經(jīng)打過補(bǔ)丁,也沒有出現(xiàn)svchost錯誤,所以就忽略了服務(wù)的檢查,沒想到這種東西還有不同的癥狀。
    這個病毒利用的是KB958644的漏洞,到微軟下載了補(bǔ)丁回來,一看才發(fā)現(xiàn)原來那臺服務(wù)器以前已經(jīng)裝過這個補(bǔ)丁。補(bǔ)丁的作用也許就是只能防止再出問題,但不能解決已有的問題,所以那臺服務(wù)器雖然裝了補(bǔ)丁,但是可能已經(jīng)被感染了,于是就沒治好。

    posted @ 2010-06-30 11:33 amp@java 閱讀(11964) | 評論 (1)編輯 收藏

    把APE、FLAC等無損壓縮音頻文件刻錄成CD的軟件有很多,搜索一把,出現(xiàn)頻率最多的是用NERO+插件,但是現(xiàn)在的NERO體積實(shí)在龐大,我嘗試下載一個NERO 10,大小不過200多M,結(jié)果安裝的時候解壓到臨時文件夾,我的C盤1G多的空間都不夠它解壓,根本就安裝不了,為了這么一點(diǎn)事情用這么大一個軟件實(shí)在沒必要,仔細(xì)搜索一下,刻錄的軟件其實(shí)有很多,都能自動地把APE刻錄到CD上,方法遠(yuǎn)比NERO簡單。
    第一個軟件是Burrrn
    Burrrn是個專門干這事的軟件,它支持的文件包括ape、flac、mp3、ogg等,實(shí)際上也是通過插件來完成編碼解碼工作的,不過這些插件都是內(nèi)置在程序包里,不用再逐個下載。它的界面非常簡單,使用也非常簡單,基本一打開就會使用。
    第二個軟件是ImgBurn
    這個軟件比較強(qiáng)大,不但能夠刻錄APE,還可以把光盤提取成鏡像、把文件或文件夾生成鏡像、把文件或文件夾刻錄到光盤上、把鏡像刻錄到光盤上,基本上NERO常用的功能都有了,軟件只有幾MB,十分環(huán)保。我下載這個軟件的時候只是想使用它的生成鏡像功能,因?yàn)橄螺d下來一些藍(lán)光原盤需要制作成ISO文件才能用POWERDVD播放。后來發(fā)現(xiàn)有人說這個軟件還可以刻錄APE,不過也需要使用相關(guān)的解碼器,只是這些解碼器在安裝常用的播放器的時候一般都已經(jīng)安裝過了,例如我以前裝過終極解碼,其中包含APE解碼器,就不需要另外安裝了。
    使用的時候只需要選擇刻錄鏡像到光盤功能,選中與APE相關(guān)的cue文件,然后就可以分軌刻錄了。

    這兩個軟件的體積都很小,而且都是免費(fèi)軟件,不但環(huán)保還合法。

    第一次使用Burrrn刻錄APE的時候,用KMPlayer播放,發(fā)現(xiàn)直接播放APE的效果跟播放刻錄出來的CD效果不一樣,CD的效果動態(tài)范圍明顯不如直接播放APE,我以為是刻錄軟件的問題,后來使用ImgBurn刻錄,也是一樣的效果。仔細(xì)對比之后發(fā)現(xiàn)KMP播放的時候是使用不同的濾鏡,可能是這個原因?qū)е滦Ч煌遣シ臕PE和播放CD又不可能使用相同的濾鏡,所以到底是什么原因也很難說得清楚,不過CD機(jī)上不認(rèn)APE,也只能這樣了。


    posted @ 2010-06-22 15:30 amp@java 閱讀(584) | 評論 (0)編輯 收藏

    1、服務(wù)命名。Oracle的服務(wù)命名就跟計算機(jī)的名稱一樣。一般來說,在局域網(wǎng)里面,計算機(jī)名稱是與IP一一對應(yīng)的,通信的時候需要使用IP,所以就有了DNS,把計算機(jī)名翻譯成IP。同樣的道理,在Oracle體系里,服務(wù)命名對應(yīng)計算機(jī)名,服務(wù)名(SID)+IP+端口+協(xié)議(TCP/IP)就對應(yīng)了計算機(jī)的IP,Oracle體系里的DNS其實(shí)就是一個配置文件,把服務(wù)命名翻譯成可以用于通信的服務(wù)名(SID)+IP+端口+協(xié)議(TCP/IP)。有趣的是,與計算機(jī)里的ping命令一樣,Oracle里面也有個TNSPing命令,通過“TNSPing 服務(wù)命名”,就會得到像ping命令相似的結(jié)果,驗(yàn)證該命名對應(yīng)的數(shù)據(jù)庫是否有效。

    2、主機(jī)身份驗(yàn)證。Oracle的一些維護(hù)工作往往需要輸入主機(jī)身份驗(yàn)證信息,但是默認(rèn)情況下,即使輸入了正確的用戶名和密碼,系統(tǒng)也會提示“用戶口令錯誤”,讓人十分困惑。其實(shí)真實(shí)的原因是,你輸入的用戶必須在“作為批處理作業(yè)登錄”里面,否則就會出現(xiàn)上述錯誤。操作方法如下:運(yùn)行-gpedit.msc-計算機(jī)配置-Windows設(shè)置-安全設(shè)置-本地策略-用戶權(quán)利指派-作為批處理作業(yè)登錄-添加用戶或組...-加入要登錄的用戶。
    執(zhí)行數(shù)據(jù)庫遷移操作的時候,可能需要在源數(shù)據(jù)庫主機(jī)和目標(biāo)數(shù)據(jù)庫主機(jī)都進(jìn)行上述操作才能成功。

    更多問題待續(xù)
    posted @ 2009-11-12 10:23 amp@java 閱讀(280) | 評論 (0)編輯 收藏

    9月10號,CHDBits開放了注冊權(quán)限,趕緊注冊了一個帳戶,這是我第一次登錄PT站。每個文件都有幾個甚至幾十個種子在等待下載者,真是“僧多粥少”。下載速度果然很猛,下了幾個文件,基本上可以達(dá)到ADSL的上限,甚至遇到了前所未有的極速,不過持續(xù)時間較短,但是平均速度都接近上限。
    然而,ADSL小水管終究不是玩PT的料,嚴(yán)格的分享率要求和ADSL龜速的上傳帶寬使得我兩天之后就變成了冰人,如果20天之內(nèi)再不提高分享率,我的帳戶將會被封禁。仔細(xì)考慮了一下,我還是“過把癮就死”算了,因?yàn)橐晕疫@8:1的上傳和下載帶寬,要長期達(dá)到要求基本上是不可能的事情,如果要我的分享率達(dá)到1:1,那我4M的下載帶寬就等于縮水成和上傳帶寬一樣,只有512K了,我裝這4M的寬帶還有什么意義?
    其實(shí)在PT站外下載,速度也是不錯的,無論是emule還是BT都能達(dá)到上限的80%以上,當(dāng)然,是在種子剛剛放出的一段時間,只要熱度一過,速度馬上下降,這是與PT沒法比的。
    還是等到哪一天光纖到戶再玩PT吧,現(xiàn)在的任務(wù)就是趁著20天沒過,趕緊“過癮”,嘿嘿!
    posted @ 2009-09-14 19:44 amp@java 閱讀(294) | 評論 (2)編輯 收藏

    VISTA和WIN7都有一種OEM激活法,該激活方式需要以下三個條件:
    1、BIOS中有相應(yīng)廠商的SLIC,VISTA要求SLIC 2.0,WIN7則要求SLIC 2.1。一般來說,品牌機(jī)的BIOS里面本來都帶有SLIC,不過有的沒打開(例如DELL的OPTIPLEX系列),需要用一些小工具打開(例如Asset);有的版本是2.0的,只能用來激活VISTA,如果要激活WIN7,需要更新SLIC,但更新官方的BIOS并不會更新SLIC,因此還需要找到專門的修改過的BIOS文件來更新。
    2、安裝的VISTA或者WIN7導(dǎo)入了相應(yīng)的OEM廠商的證書,如果安裝的系統(tǒng)是OEM版的,安裝完之后證書就在里面了;如果安裝的是普通版本的,還需要手動導(dǎo)入,命令為:
    slmgr.vbs -ilc <證書路徑>
    一般每個廠商都只有一個證書,而且VISTA和WIN7的證書是相同的,也就是說相同的證書可同時用于VISTA或者WIN7。
    3、所安裝的VISTA或WIN7的key,與證書不同,key是每個版本的Windows一個,HomeBasic,HomePremium,Business,Ultimate等版本分別有各自的key,VISTA和WIN7的key也是不同的。導(dǎo)入key的方式是運(yùn)行以下命令:
    slmgr.vbs -ipk <key>
    如果安裝的時候輸入了相應(yīng)的key就不用這一步了。

    同時具備了上述條件的VISTA和WIN7就被激活了,這些條件不需要按順序來準(zhǔn)備,只要具備即可,也就是說系統(tǒng)安裝后再刷BIOS,或者系統(tǒng)安裝前刷BIOS都是可以的。
     關(guān)于BIOS的信息,可瀏覽: 
    http://www.bios.net.cn

    關(guān)于Windows的信息,可瀏覽:
    http://www.pcbeta.com
    posted @ 2009-08-17 21:22 amp@java 閱讀(356) | 評論 (0)編輯 收藏

    jQuery UI里面只有一個DatePicker,只能選擇日期,不能選擇時間,有人做了一個可以選擇時間的DateTimePicker,在這里(http://razum.si/jQuery-calendar/TimeCalendar.html)可以看到,把jquery.js,jquery-calendar.js,jquery-calendar.css下回來之后就可以用了。
    但是有幾個Bug需要自己修改:
    1、當(dāng)輸入框里面的時間是0點(diǎn)時,控件顯示不完整,這是因?yàn)橛袀€函數(shù)有bug,如下所示:

    ???? /* ?Ensure?numbers?are?not?treated?as?octal.? */
    ????trimNumber:?
    function (value)?{
    ????????
    if ?(value? == ?'')
    ????????????
    return ?'';
    ????????
    while ?(value.charAt( 0 )? == ?' 0 '? )?{
    ????????????value?
    = ?value.substring( 1 );
    ????????}
    ????????
    return ?value;
    ????},

    ???????? while ?(value.charAt( 0 )? == ?' 0 '? )?{
    ????????????value?
    = ?value.substring( 1 );
    ????????}

    這一句,如果是0點(diǎn)的話,最終會出錯,因?yàn)樗拈L度最后是1,不能執(zhí)行substring(1),改成下面就好了:

    ???? /* ?Ensure?numbers?are?not?treated?as?octal.? */
    ????trimNumber:?
    function (value)?{
    ????????
    if ?(value? == ?'')
    ????????????
    return ?'';
    ????????
    while ?(value.charAt( 0 )? == ?' 0 '? && ?value.length >1 )?{
    ????????????value?
    = ?value.substring( 1 );
    ????????}
    ????????
    return ?value;
    ????},

    2、作者是在jQuery 1.1.2版本下實(shí)現(xiàn)的,現(xiàn)在最新版本是1.3.2,這個控件在1.3.2下會出現(xiàn)異常,不能選擇日期,這是因?yàn)橛袔讉€選擇器有問題:
    ?1?????????$('.calendar_daysRow?td[a]').hover(?//?highlight?current?day
    ?2?????????????function()?{
    ?3?????????????????$(this).addClass('calendar_daysCellOver');
    ?4?????????????},?function()?{
    ?5?????????????????$(this).removeClass('calendar_daysCellOver');
    ?6?????????});
    ?7?????????$('.calendar_daysRow?td[a]').click(function()?{?//?select?day
    ?8?????????????popUpCal.selectedDay?=?$("a",this).html();
    ?9?????????????popUpCal.selectDate();
    10?????????});
    上面的$('.calendar_daysRow?td[a]')在jQuery 1.3.2中不能使用,$("a",this)也是有問題的,同時,在FireFox中,<a>的不能設(shè)置背景顏色,所以hover函數(shù)不起作用,把它設(shè)在<td>也能達(dá)到相同的效果,改成以下代碼即可:
    ?1?????????//$('.calendar_daysRow?td?a').hover(?//?highlight?current?day
    ?2?????????$('.calendar_daysRow?td').hover(?//?highlight?current?day
    ?3?????????????function()?{
    ?4?????????????????$(this).addClass('calendar_daysCellOver');
    ?5?????????????},?function()?{
    ?6?????????????????$(this).removeClass('calendar_daysCellOver');
    ?7?????????});
    ?8?????????//$('.calendar_daysRow?td[a]').click(function()?{?//?select?day
    ?9?????????$('.calendar_daysRow?td?a').click(function()?{?//?select?day
    10?????????????//alert("click");
    11?????????????//popUpCal.selectedDay?=?$("a",this).html();
    12?????????????popUpCal.selectedDay?=?$(this).html();
    13?????????????popUpCal.selectDate();
    14?????????});

    經(jīng)過修改之后在IE7和FireFox3都能在jQuery 1.3.2環(huán)境下正常運(yùn)行。
    posted @ 2009-05-22 19:37 amp@java 閱讀(41556) | 評論 (19)編輯 收藏

    初次使用jQuery,發(fā)現(xiàn)真是個好東西,把很多東西都簡化了,循環(huán)基本上都去掉了,可以說是開創(chuàng)了JS的一種新模式,雖然開始覺得有點(diǎn)不習(xí)慣,但是很容易學(xué)習(xí)也很容易看懂。一個神奇的$原來有那么多的功能,很強(qiáng)大,呵呵。
    最讓人欣慰的是它屏蔽了所有瀏覽器的差別,可以在各種瀏覽器上用相同的代碼實(shí)現(xiàn)相同的效果。

    posted @ 2009-05-21 18:42 amp@java 閱讀(263) | 評論 (0)編輯 收藏

    二維條形碼比普通的條形碼能保存更多的信息,已經(jīng)應(yīng)用到很多領(lǐng)域里面。例如手機(jī)電影票,就是一個嵌在彩信里面的二維碼圖像。南航也推出了網(wǎng)上辦理登機(jī)牌業(yè)務(wù),辦理完成之后往手機(jī)發(fā)送一條包含二維碼的彩信,到了機(jī)場就可以通過自助設(shè)備掃描二維碼,打印登機(jī)牌。
    然而,專業(yè)的二維碼掃描設(shè)備價格十分昂貴,最便宜的都在1000元以上,到淘寶上搜搜就知道了。借助Java和一個開源的庫,我們卻可以通過普通的網(wǎng)絡(luò)攝像頭實(shí)現(xiàn)相同的效果,成本只需要幾十塊。
    Open Source QR Code Library是一個開源的QR Code(二維條形碼的一種)生成和讀取的庫,官方網(wǎng)站為:http://qrcode.sourceforge.jp/,里面包含了生成和讀取QR Code的所有代碼,其中有個jmfexample就能實(shí)現(xiàn)通過攝像頭讀取QR Code,經(jīng)過本人嘗試,幾十塊的普通攝像頭效果已經(jīng)不錯了,一次讀取幾百字節(jié)都沒問題。
    使用這個庫的步驟如下:
    1、到其官方網(wǎng)站下載回來;
    2、到sun的網(wǎng)站下載JMF包并安裝;
    3、插上攝像頭,打開我的電腦,查看是否出現(xiàn)“USB視頻設(shè)備”,然后打開,看攝像頭工作是否正常
    4、運(yùn)行JMF里面的JMF Registry程序,點(diǎn)擊“Detect Capture Devices”,查找視頻設(shè)備,查找到之后會在左邊的列表里出現(xiàn)“vfw:Microsoft WDM Image Capture (Win32):0”類似的設(shè)備,點(diǎn)擊就會在右邊出現(xiàn)其詳細(xì)信息,我的攝像頭是這樣的:
    Name = vfw:Microsoft WDM Image Capture (Win32):0

    Locator = vfw://0

    Output Formats---->

    0. javax.media.format.YUVFormat
    ? YUV Video Format: Size = java.awt.Dimension[width=640,height=480] MaxDataLength = 614400 DataType = class [B yuvType = 32 StrideY = 1280 StrideUV = 1280 OffsetY = 0 OffsetU = 1 OffsetV = 3

    1. javax.media.format.YUVFormat
    ? YUV Video Format: Size = java.awt.Dimension[width=160,height=120] MaxDataLength = 38400 DataType = class [B yuvType = 32 StrideY = 320 StrideUV = 320 OffsetY = 0 OffsetU = 1 OffsetV = 3

    2. javax.media.format.YUVFormat
    ? YUV Video Format: Size = java.awt.Dimension[width=176,height=144] MaxDataLength = 50688 DataType = class [B yuvType = 32 StrideY = 352 StrideUV = 352 OffsetY = 0 OffsetU = 1 OffsetV = 3

    3. javax.media.format.YUVFormat
    ? YUV Video Format: Size = java.awt.Dimension[width=320,height=240] MaxDataLength = 153600 DataType = class [B yuvType = 32 StrideY = 640 StrideUV = 640 OffsetY = 0 OffsetU = 1 OffsetV = 3

    4. javax.media.format.YUVFormat
    ? YUV Video Format: Size = java.awt.Dimension[width=352,height=288] MaxDataLength = 202752 DataType = class [B yuvType = 32 StrideY = 704 StrideUV = 704 OffsetY = 0 OffsetU = 1 OffsetV = 3

    注意,其中Output Formats都是javax.media.format.YUVFormat,而QR Code Library里默認(rèn)的設(shè)備不是這種格式的,所以需要對源碼作一定的修改。

    5、用Eclipse打開QR Code Library的源碼,作出一些適當(dāng)?shù)男薷模?br />如果攝像頭是上面所說的只支持YUV格式,則需要修改jp.sourceforge.qrcode.example.jmf.camDataSource.java,把setMainSource函數(shù)里的
    VideoFormat vidformat = new VideoFormat(VideoFormat.RGB);
    修改為
    VideoFormat vidformat = new VideoFormat(VideoFormat.YUV);
    否則永遠(yuǎn)也找不到攝像頭。

    6、把JMF包里的jmf.jar放到Classpath里
    7、執(zhí)行jp.sourceforge.qrcode.example.jmf.jmfexample,搞定

    當(dāng)然,由于源碼開放的,只要符合許可,你想怎么改都行,可以把它嵌入到某個應(yīng)用程序里面,這個程序就具有了掃描QR Code的功能了。

    posted @ 2009-04-02 16:22 amp@java 閱讀(5936) | 評論 (13)編輯 收藏

    今天早上回到單位發(fā)現(xiàn)好幾部服務(wù)器都出現(xiàn)了與svchost.exe有關(guān)的錯誤,有一臺svchost.exe進(jìn)程占用CPU達(dá)到100%,慢如蝸牛。普通PC機(jī)上則出現(xiàn)網(wǎng)絡(luò)時斷時續(xù),重啟后能打開網(wǎng)頁,但很快就所有網(wǎng)頁打不開,某些網(wǎng)絡(luò)程序運(yùn)行時則出現(xiàn)緩沖區(qū)已滿等錯誤。更新病毒庫查毒后發(fā)現(xiàn)整個局域網(wǎng)的所有電腦都出現(xiàn)Hack.Exploit.Win32.MS08-067.k病毒,殺毒軟件顯示svchost.exe里的病毒已清除,但是重啟又出現(xiàn)。
    搜索得知這是MS08-067漏洞導(dǎo)致,于是下載補(bǔ)丁,打上,但是病毒并沒有清除。無奈只能求助高人,在高人指點(diǎn)下找到了病毒位置并清之,過程如下:
    1、運(yùn)行,輸入services.msc,打開服務(wù)管理器,按照“描述”排序,在“描述”欄為空的那幾項(xiàng)服務(wù)中查找一個名字很奇怪、由幾個隨機(jī)字符組成、沒有任何意義的服務(wù),它的狀態(tài)一般是停止,但是啟動模式是自動,這里要把它改成已禁用;
    2、重啟電腦;
    3、運(yùn)行,輸入regedit,打開注冊表編輯器,輸入那個奇怪服務(wù)的名字進(jìn)行查找,找到以那個名字命名的鍵值,在其下面有個名為Parameters的子鍵,該子鍵內(nèi)有個ServiceDll的字符串值,就是病毒文件所在,找到那個病毒文件并刪之;
    4、到微軟網(wǎng)站下載MS08-067補(bǔ)丁,打上,搞定!

    這是我第一次碰到這種迅速感染整個局域網(wǎng)的病毒,似乎跟當(dāng)年的沖擊波有得比,搞起來煩得要命,幾十臺機(jī)啊……
    posted @ 2009-01-08 23:05 amp@java 閱讀(5098) | 評論 (2)編輯 收藏

    現(xiàn)在的手機(jī)大多具有藍(lán)牙功能,手機(jī)上的JavaME程序也能訪問藍(lán)牙端口,藍(lán)牙的協(xié)議有多種,但最簡單的可能就是虛擬串口(rfcomm)協(xié)議了,在該協(xié)議中,藍(lán)牙端口被虛擬成一個串口,只要獲取其InputStream和OutputStream后,就可以進(jìn)行讀寫操作了,與socket差不多。 待續(xù)…
    posted @ 2008-11-27 19:16 amp@java 閱讀(871) | 評論 (0)編輯 收藏

    為了充分利用晚上的帶寬,我搞了一部專門的破機(jī)用于BT/EMULE下載,上班時間為了不影響大家上網(wǎng),必須停止下載任務(wù)。有的下載工具本身帶有計劃任務(wù)功能,但是有些只能控制速度,不能控制連接,例如eMule,雖然可以停止下載,但是連接還是很多的,脆弱的ADSL路由/Modem經(jīng)不起大量的連接,很容易就死翹翹了。這種情況下,最痛快的解決辦法是拔線,但是每天插拔也不是辦法,軟一點(diǎn)的辦法是禁用網(wǎng)卡,但是每次手動操作也不是辦法。更直接的辦法就是計劃任務(wù)自動啟用/禁用網(wǎng)卡了。要實(shí)現(xiàn)這種目的必須要有能夠自動運(yùn)行的工具,devcon就是一個命令行工具,能夠在命令行中實(shí)現(xiàn)“設(shè)備管理器”的功能,我這里只要“啟用/禁用”功能即可。
    devcon的下載地址:
    http://support.microsoft.com/kb/311272/zh-cn
    微軟出品,權(quán)威產(chǎn)品。

    使用的時候還是有點(diǎn)小問題,搜索了一下找不到答案,只有自己解決了:
    1、禁用設(shè)備的命令是:
    devcon disable 設(shè)備ID
    這個設(shè)備ID怎么得到呢?通過設(shè)備管理器,在設(shè)備上點(diǎn)擊“屬性”,在“詳細(xì)信息”標(biāo)簽里面有個下拉列表,選擇“設(shè)備范例Id”,下面顯示出來的就是設(shè)備ID,
    怎么把這個ID復(fù)制出來呢?右鍵是沒辦法的,但是直接CTRL+C就OK了。
    2、設(shè)備ID不能直接輸入,否則會把ID開頭相同的一大堆設(shè)備都操作一遍,最后還會出幾個錯誤提示;加上雙引號也不行,會提示沒有設(shè)備被禁用/啟用;必須這樣寫:@"設(shè)備ID",所以最后的命令格式是:
    devcon disable @"設(shè)備ID"
    不知道是什么道理。

    在計劃任務(wù)里面添加兩個任務(wù):“啟用網(wǎng)卡”,“禁用網(wǎng)卡”,分別用devcon enable,devcon disable命令即可,例如早上8點(diǎn)半禁用,晚上23:30啟用(有部分好筒子晚上加班)。這樣一來,就可以24小時開著那幾個下載程序也不會有影響了,在網(wǎng)卡禁用的時候,無論它們怎么嘗試連接,都跳不出如來佛的掌心。

    posted @ 2008-08-28 17:19 amp@java 閱讀(3283) | 評論 (3)編輯 收藏

    說來慚愧,雖然工作學(xué)習(xí)都離不開計算機(jī),但直到兩個星期以前,我還沒有為自己買過一臺新電腦,倒是給人家裝了快10臺。近段時間終于下定決心買臺電腦了。我不玩游戲,買電腦只是為了上網(wǎng),看片,寫點(diǎn)小程序。現(xiàn)在流行高清電影,上了一下相關(guān)論壇,發(fā)現(xiàn)要流暢“軟解”H264編碼的1080P電影,至少需要4核的CPU,Intel的Q6600盒裝1500左右,AMD 羿龍9550 1100左右,前者的性能好于后者,但是Intel的集成主板又貴又爛,AMD 的780G芯片組是目前最強(qiáng)的整合芯片組,價格便宜量又足,于是就把架構(gòu)定在AMD上。技嘉的GA-MA78GM-S2H 是論壇上討論最多的主板,應(yīng)該也是用的人最多的780G主板之一,憑借技嘉優(yōu)秀的做工,充足的用料,豐富的接口,贏得了廣泛的好評,但是這個是小板,由于面積的局限,南北橋芯片發(fā)熱比較厲害。后來技嘉推出了標(biāo)準(zhǔn)ATX板型的GA-MA78G-DS3H ,采用了全固態(tài)電容(小板是供電部分全固態(tài)),減少了一個ESATA接口,增加了一個1394接口,增加了三條PCI-E插槽,散熱效果應(yīng)該比小板好,于是就定下了這塊主板。由于高清電影動輒10G以上,所以買了個希捷500G 7200.11硬盤,以后降價的話再加一個做RAID 0就爽了。內(nèi)存選用kingston 1G * 2 DDR2-800組成雙通道。光驅(qū)是明基DW2000 DVD刻錄機(jī)。這些都很快定下來了,倒是機(jī)箱和電源費(fèi)了不少腦筋。看了不少評論和測評,最后才定下了航嘉的“時光之門”機(jī)箱,看中的就是它的用料和4個前置USB+一個1394口。電源要選主動PFC,效率更高,同時也要額定400W以上,因?yàn)槟莻€CPU的TDP就有95W,挑了半天,定在TT的KK500A,額定功率400W,主動PFC,14CM大風(fēng)扇。顯示器22寸液晶就可以了,我對它的要求不高,因?yàn)榭雌脑捯彩峭ㄟ^HDMI接到液晶電視上看,初步?jīng)Q定三星2243BW。
    這一切準(zhǔn)備好之后,找了個時間殺到電腦城。報價如下:
    CPU     Phenom X4 9550 盒裝 1120
    主板 技嘉GA-MA78G-DS3H  680
    內(nèi)存 Kingston DDR2-800 1G*2 140*2=280
    硬盤 希捷7200.11 500GB 585
    光驅(qū) BenQ DW2000 DVD刻錄機(jī) 225
    機(jī)箱 航嘉時光之門H301 265
    電源 TT KK500P (KK500A的升級版) 470
    顯示器 三星 2243BW 1850
    鍵盤鼠標(biāo) 雜牌套裝 30
    合計 5505

    挑好之后我讓JS備貨,然后就回去了。過了沒多久,JS打電話來說AMD的那個CPU沒貨,問我要不要9750,我說算了,等有貨再裝吧,那個CPU的TDP 125W,太恐怖。結(jié)果過了兩天,還是沒貨,我打電話問了本市的其他電腦店,也是沒貨,說是奧運(yùn)影響了物流(不得不說奧運(yùn)真是勞民傷財,個人觀點(diǎn),不要上綱上線)。JS出了個主意說讓我先用雙核的4800+,有貨的時候再換成9550。開始的時候我不同意,考慮到淘寶自己買,問了一下真的有賣的,還比JS那里便宜20塊,但是又怕出現(xiàn)問題不知道找誰,雖然盒裝全國聯(lián)保,但是我這個小地方好像沒有AMD的代理。最后還是同意了JS的辦法,再奔電腦城,把裝了4800+的主機(jī)扛了回來。顯示器我問過三星的代理,只要1790,JS說他賣不了這個價,于是就不要顯示器,鍵盤鼠標(biāo)看了一下,也很爛,不要。回來打開電腦,我靠,居然一點(diǎn)聲音都沒有,真的,從來沒見過這么安靜的電腦,如果不是燈亮著,跟沒開一個樣。可能歸功于電源那14cm的風(fēng)扇,只要很低的轉(zhuǎn)速就可以產(chǎn)生大風(fēng)量。上淘寶買了根3米長的HDMI線,接到家里的32寸液晶上,很郁悶地發(fā)現(xiàn)不能點(diǎn)對點(diǎn),那個電視的物理分辨率是1366*768,但卻不支持這個輸入分辨率。沒辦法,只好用1280*720輸入,看文字比較模糊,但也沒多大影響。看電影那叫一個爽,比電腦上爽多了。
    前天去電腦城買了一套雙飛燕的防水鼠標(biāo)鍵盤套裝KB-827D,65塊。昨天和一個同事一起想去買三星的那款顯示器,無意中卻看到了一款A(yù)OC的2280V,參數(shù)和三星2243BW基本一樣,但是價格便宜不少,只要1540,還帶DVI線,3年質(zhì)保,比三星的D-SUB線+1年質(zhì)保要好。于是就要了一臺,店家包無點(diǎn),開箱檢查了一下,兩臺都是完美屏,拿回來了。
    這個過程中,最郁悶的事情是弄那幾個顯示接口了。780G的主板一般都帶有D-SUB、DVI-D、HDMI三種接口,但是DVI和HDMI接口不能同時使用。技嘉的這塊主板就是這樣,而且還是自動選擇HDMI,也就是插上DVI和HDMI之后只有HDMI有東西。AOC的那兩個接口也是自動選擇,也就是兩個接口都插上的話,就會自動選擇DVI(本來可以手動選擇的,但是如果兩個都插上的話好像手動選擇無效)。
    首先碰到的問題是聲音。按照主板的說明書,如果需要通過HDMI口輸出聲音的話,必須在控制面板->聲音和音頻設(shè)備->音頻里面在聲音播放默認(rèn)設(shè)備下選擇Realtek HDA HDMI Out。但是我把電腦搬回單位折騰的時候,發(fā)現(xiàn)這里并沒有出現(xiàn)Realtek HDA HDMI Out這個選項(xiàng),只有Realtek HD Audio output!在設(shè)備管理器里卻能發(fā)現(xiàn)ATI HDMI Audio這個設(shè)備。搜索了半天,好像有人遇到過這個問題,但是沒有答案;有人說在BIOS里面開啟,但我發(fā)現(xiàn)默認(rèn)已經(jīng)開啟了;打電話給技嘉客服,那個人叫我先接上電視試試。那時候還沒有買HDMI線,試不了,于是就不管它了。結(jié)果HDMI線到了之后,一接上電視,馬上就出聲了,暈啊,原來必須插上HDMI線之后才能選擇那個Realtek HDA HDMI Out!!!!
    昨天把顯示器買回來之后也碰到問題了。我把DVI口和D-SUB口和HDMI口都接上了,啟動電腦,顯示器自動選擇DVI輸入,自檢界面->Windows滾動條都沒問題,但是滾動條過去之后,顯示器提示沒信號,黑屏了,怎么按都沒反應(yīng),選擇信源也不行。只能關(guān)機(jī)重啟,然后按F8選擇VGA模式,進(jìn)去之后分辨率是640*480,沒問題,但是只要一調(diào)整分辨率,無論是調(diào)成800*600還是1680*1050,都一樣的沒信號,黑屏。把D-SUB線和DVI線分別拔下,還是不行。想到ATI控制中心里面看看,結(jié)果偏偏在這個時候ATI控制中心啟動不了!!重裝驅(qū)動,還是不行。下載最新的8.7的催化劑驅(qū)動,一裝完重啟就藍(lán)屏。只要又裝回8.6版。搞了三四個小時,弄到最后,把HDMI線拔了下來,只接一個DVI到顯示器,居然一切正常了,啟動成功,分辨率1680*1050,完美。仔細(xì)一想,才明白原來這塊主板只支持DVI和HDMI其中之一輸出,而且接上HDMI后默認(rèn)就輸出HDMI了,雖然我那電視一直沒開,但是線插上之后就不再輸出DVI了。把DVI拔了之后,由于之前只有電視作為顯示器,沒有配置雙顯示器輸出,所以D-SUB也不會有信號,所以無論拔DVI還是拔D-SUB都沒信號,只有拔HDMI才行。這時候我又嘗試安裝中文版的8.6 ATI控制中心,裝完之后還是啟動不了,嘗試一下Restart Runtime,我靠,居然就可以啟動了!!神奇!!!進(jìn)去把顯示器作為主顯示,電視作為擴(kuò)展。重啟之后顯示器和電視機(jī)都能顯示了,而且顯示器是1680*1050,電視是1280*720,調(diào)整了一下電視的過掃描,使它滿屏,然后用KMPlayer放電影,把窗口拖到電視那邊,全屏,好了,可以一邊在書房上網(wǎng)一邊在客廳放電影了(我在書房和客廳之間的墻上打了個洞)!!有點(diǎn)遺憾的是,顯示器只能用D-SUB輸入,浪費(fèi)了那根DVI線。不過這個可以通過獨(dú)立顯卡來解決,以后再說吧。
    780G主板的確厲害,集成的顯卡可以輕松硬解1080P的視頻,CPU占用不到10%,但是有時候會出現(xiàn)綠格子,還有一些奇怪的現(xiàn)象。所以可能的話我還是盡量使用軟解。不過到目前為止,4核CPU還沒到貨,這個4800+軟解VC1有時候都會卡,更別說H264了。而且AMD那個原裝風(fēng)扇實(shí)在太爛了,看片的時候60多度,甚至死機(jī),必須把蓋子打開,拿個臺扇往里吹才能把一部片子看完。后來花10塊買了個12cm的機(jī)箱風(fēng)扇,裝上之后似乎也沒什么效果。看來只能換CPU散熱器了,初步?jīng)Q定買個九州風(fēng)神的β400+,100左右,4根熱管的,對付那個9550應(yīng)該可以吧。不過要等CPU到了再買。突然發(fā)現(xiàn),DIY就是個燒錢的過程,我多年的積蓄已經(jīng)花得差不多了……
    到目前投入的錢:
    主機(jī)3625+顯示器1540+機(jī)箱風(fēng)扇10+HDMI線190+鼠標(biāo)鍵盤65=5430
    預(yù)計還要投入的散熱器,突破5500了!!
    這就是我的第一臺自用新電腦。

    2008年9月6日更新:
    截至目前,已在淘寶上購入如下附件:
    1、九州風(fēng)神β400+散熱器一個,連郵費(fèi)102塊。買回來裝上才發(fā)現(xiàn)噪音太大了,不得已只好DIY了一下,把風(fēng)扇拆掉,裝上原裝散熱器的風(fēng)扇。
    2、為了在客廳控制電腦,買了個無線鼠標(biāo),太科的,可能是山寨貨,連郵費(fèi)82,剛開始的時候直接在客廳就可以穿墻控制書房的電腦了,不過第二次就不行了,可能電力不足吧,現(xiàn)在只能把鼠標(biāo)拿到墻邊才能有,已經(jīng)買了一條5m的USB延長線,明天送貨。
    posted @ 2008-07-27 21:35 amp@java 閱讀(481) | 評論 (2)編輯 收藏

         摘要: Nokia MMS Library是一個開放源代碼的Java MMS開發(fā)包,里面包含了源碼、文檔、示例程序等,很容易就能學(xué)會。下面是用這個包發(fā)送彩信的方法: 1、電腦通過GPRS/EDGE MODEM或手機(jī)連接移動夢網(wǎng),注意,必須是移動夢網(wǎng)(CMWAP),不是互聯(lián)網(wǎng)(CMNET),如果手動撥號,一般是撥*99***1#或*99***2#,撥通之后打開命令行窗口,telnet 10.0.0.172...  閱讀全文
    posted @ 2008-06-17 14:35 amp@java 閱讀(3466) | 評論 (11)編輯 收藏

    這幾天要在單位部署一個軟件包,是msi形式的,據(jù)說可以通過“域推送”的形式安裝,搜索了一下,發(fā)現(xiàn)需要在 組策略->軟件設(shè)置->軟件安裝 里面添加放在共享目錄里的軟件包。但是我試過無論在“計算機(jī)配置”里面還是在“用戶配置”里面添加那個軟件包,無論是“發(fā)布”還是“指派”,都沒辦法自動安裝,最多只是在“添加刪除程序”里面的“添加新程序”出現(xiàn)那個軟件包,還需要手動安裝。
    域控制器上按照部門劃分了多個組織單位(OU),并把用戶分配到各自的組織單位中,組策略就是在這些組織單位上面應(yīng)用的。
    昨天晚上看了一下“Windows2000資源大全”,里面有講到這種軟件安裝方法。原來是要把計算機(jī)也劃分到組織單位中,然后在那個組織單位的組策略的“計算機(jī)配置”里面設(shè)置那個軟件包,當(dāng)計算機(jī)啟動后,進(jìn)入“應(yīng)用計算機(jī)設(shè)置”階段,還沒出現(xiàn)登錄界面時,就會自動安裝。之前對組策略的理解有問題,以為組策略只應(yīng)用于用戶,實(shí)際上是“用戶配置”應(yīng)用于用戶,“計算機(jī)配置”應(yīng)用于計算機(jī),要對讓每臺計算機(jī)自動安裝,而不是在用戶登錄之后安裝,就必須在“計算機(jī)配置”里面設(shè)置,要把這個設(shè)置應(yīng)用于所有計算機(jī),就要把那些計算機(jī)劃分到某個組織單位,然后對這個組織單位應(yīng)用組策略。

    之前嘗試過用另外一種方法實(shí)現(xiàn)軟件的自動安裝,這種方法不僅僅適用于msi,還適用于所有安裝文件。
    利用Windows的WMI服務(wù),可以對遠(yuǎn)程用戶的注冊表進(jìn)行操作,在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce里面添加一個值為安裝文件路徑的字符串,就會在計算機(jī)啟動并登錄后執(zhí)行該安裝文件,執(zhí)行完畢后會把這個鍵值刪除,也就是只執(zhí)行一次。
    利用PsTools,可以對遠(yuǎn)程計算機(jī)進(jìn)行重啟操作,當(dāng)計算機(jī)重啟后,用戶登錄時,就會執(zhí)行安裝過程。如果不需要倒計時重啟,還可以通過WMI服務(wù)進(jìn)行重啟操作,這樣就可以完全通過Script來實(shí)現(xiàn),并且能夠記錄操作的成功與否。
    通過以下代碼可以連接遠(yuǎn)程計算機(jī):
    Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
    Set objWMIService = objSwbemLocator.ConnectServer(strComputer,"root\default",strUser,strPassword,"MS_409","ntlmdomain:")
    其中strComputer是遠(yuǎn)程計算機(jī)名,strUser是域管理員帳號,strPassword是域管理員密碼
    得到objWMIService之后,就可以像對本機(jī)一樣操作WMI,例如獲取注冊表操作類StdRegProv:
    Set objStdRegProv = objWMIService.Get("StdRegProv")
    關(guān)于遠(yuǎn)程注冊表操作可以查看MSDN里的StdRegProv類說明。
    通過Win32_OperatingSystem類可以實(shí)現(xiàn)對遠(yuǎn)程計算機(jī)的關(guān)機(jī)、重啟等操作。
    WMI是個強(qiáng)大的工具,在局域網(wǎng)中可以實(shí)現(xiàn)很多方便的管理操作。但是需要通過VBScript來實(shí)現(xiàn),而VBScript的異常處理十分弱智;使用JScript的話,很多WMI類的操作又十分繁瑣。
    posted @ 2008-06-14 16:12 amp@java 閱讀(1093) | 評論 (0)編輯 收藏

        JSF只能采用POST的方法進(jìn)行FORM提交,同一頁面要顯示不同的內(nèi)容,只有通過POST來改變參數(shù)或者通過SESSION傳遞變量。有時候有大量相似的頁面,這些頁面只有很少一部分不同(例如不同用戶、不同角色、不同頁碼等),通過跟在URL后面的query string本來可以很容易地實(shí)現(xiàn),但在JSF里卻不行,只要一提交,馬上就把?后面那串東西丟掉。假如有一個頁面,根據(jù)URL后面的id參數(shù)來顯示FORM的內(nèi)容,提交的時候如果驗(yàn)證出錯,那個FORM的內(nèi)容就丟失了,顯示一個莫名其妙的頁面,因?yàn)檫@時候那個id參數(shù)已經(jīng)沒有了。還有常用的分頁操作,本來在URL后面加上個頁碼就可以了,但是JSF的分頁控件卻只能通過POST來翻頁,一刷新就出來個“重試”“取消”的對話框,讓人煩惱。如果頁面內(nèi)容根據(jù)不同用戶角色有細(xì)微不同,就得每個角色建立一個頁面,每個頁面對應(yīng)一個managed bean,這些頁面的內(nèi)容基本相同,bean的內(nèi)容也基本相同,卻要分別建立,一點(diǎn)重用的機(jī)會都沒有。今天做的一個東西就遇到了這種問題:
    一個簡單的審批流程,只有3個角色,申請者、審批者、執(zhí)行者,整個流程是這樣的:申請者填單->審批者查看并審批->執(zhí)行者執(zhí)行并填入結(jié)果->申請者查看。這樣,每種角色都有兩種列表:未回復(fù)和已回復(fù),這兩種列表在三個角色里面都是相似的,但有細(xì)微區(qū)別:
    申請者 審批者 執(zhí)行者
    未回復(fù)列表 自己已發(fā)出但未被執(zhí)行者執(zhí)行的列表 申請者已提交但自己未審批的列表 審批已通過但自己未執(zhí)行的列表
    已回復(fù)列表 自己已發(fā)出且執(zhí)行者已執(zhí)行的列表 申請者已提交且自己已審批的列表 審批已通過且自己已執(zhí)行的列表

    這些列表的不同之處在于:已登錄用戶的角色(可以從session中得到,但一個用戶可能有多種角色,他可能以不同的角色查看列表),列表的當(dāng)前狀態(tài)(對每種角色都有兩種狀態(tài)),列表的頁碼。由于每個列表都有可能有大量數(shù)據(jù),所以必須用到分頁。通過JSF的DataTable空間和DataScroller控件可以簡單地實(shí)現(xiàn)分頁,然而,這種分頁導(dǎo)致URL后面的參數(shù)無效了,這樣一來,這六種列表就必須通過6個頁面來顯示了,通過頁面的名稱來區(qū)分當(dāng)前用戶的角色、所查看的列表的狀態(tài),每個頁面通過POST來決定頁碼。本來一個頁面+一個bean+3個參數(shù)就可以決定,現(xiàn)在需要6個頁面+6個bean來完成了。

    list.jsp?type=0&role=0&page=1->type0_role0.jsp
    list.jsp?type=0&role=1&page=1->type0_role1.jsp
    list.jsp?type=0&role=2&page=1->type0_role2.jsp
    list.jsp?type=1&role=0&page=1->type1_role0.jsp
    list.jsp?type=1&role=1&page=1->type1_role1.jsp
    list.jsp?type=1&role=2&page=1->type1_role2.jsp

    假如有n種狀態(tài)m種角色那豈不是要n*m個頁面+n*m個bean?

    有點(diǎn)想放棄JSF這個雞肋了。

    希望有高手給條生路走走!
    posted @ 2008-06-04 19:48 amp@java 閱讀(2349) | 評論 (11)編輯 收藏

    剛剛才知道,原來Java的線程是不能重啟的,也就是說,當(dāng)線程的run()方法執(zhí)行到最后一行,退出之后,這個線程就結(jié)束了,不能再通過start()方法重啟啟動這個線程,只能重新構(gòu)造一個線程對象,再調(diào)用其start()方法來啟動,但這個對象和原來那個對象已經(jīng)不同了。
    為了實(shí)現(xiàn)某個線程對象的“重啟”功能,可以在它的run()方法的最外層加上一個循環(huán)語句:
    1 public void run(){
    2   while(!stop){
    3     //do something
    4   }
    5 }

    這樣,只要stop不為true,run()方法就不會結(jié)束,不斷地“重啟”。
    如果run()方法里面還有一個循環(huán),那么就要兩個停止標(biāo)志:
    1 public void run(){
    2   while(!stop){
    3     //do something
    4     while(!stop && !restart){
    5       //do other thing
    6     }
    7   }
    8 }
    9 
    這樣,如果需要“重啟”線程,只要把restart設(shè)為true即可,如果要退出線程,只要把stop設(shè)為true即可。
    posted @ 2008-04-22 10:56 amp@java 閱讀(4187) | 評論 (0)編輯 收藏

    之前用過一個帶CheckBox的Tree控件,叫dhtmlXTree,支持xml數(shù)據(jù),功能很好很強(qiáng)大,但是有個問題怎么也解決不了,不知道什么原因,就是第一次顯示的時候能夠正常顯示樹形列表,但第二次進(jìn)入相同頁面就會顯示錯誤,所有圖片都看不見,只看到其中的文字,而且這時候整個瀏覽器像死了一樣,點(diǎn)擊上面的任何鏈接都沒反應(yīng),必須關(guān)閉重新打開才有效,或者等上十幾分鐘才反應(yīng)過來,不知道是不是一直在后臺運(yùn)行某個Javascript腳本。雖然這個控件的源代碼可以看到,但是一條注釋都沒有,都不知道哪個部分出了問題。

    在google上搜索替代方案時,看到了BlueShoes的樹形控件,具有多種形態(tài),包括CheckBox,RadioButton等,每種形態(tài)都有例子,而且有詳細(xì)的規(guī)范的文檔(phpdocument,與JavaDoc類似),關(guān)鍵是代碼里面也有詳細(xì)的注釋,可以看到每個部分的實(shí)現(xiàn)原理。與dhtmlXTree使用XML存儲數(shù)據(jù)不同的是,這個樹形控件使用多維數(shù)組來存儲數(shù)據(jù),似乎可讀性和效率稍差,但出錯的幾率也少了,不需要用到瀏覽器的XML處理。與前者一樣也支持IE5。

    關(guān)于BlueShoes的樹形控件的詳細(xì)的情況可以看這里:http://www.blueshoes.org/en/javascript/tree/

    那個網(wǎng)站上還有很多其他控件,也是很優(yōu)秀的,雖然它的后臺是php框架,但客戶端控件同樣可以用于JSP。
    posted @ 2008-02-26 11:28 amp@java 閱讀(457) | 評論 (0)編輯 收藏

    瀏覽器的緩存有時候顯得很討厭,明明已經(jīng)更新了內(nèi)容,就是不顯示新的,只要URL不變,瀏覽器就不會去檢查服務(wù)器是否已經(jīng)更新,而是用緩存里的東西,起碼在IE里是這樣。
    使用AJAX經(jīng)常需要動態(tài)更新某一過程的狀態(tài),例如短信發(fā)送的狀態(tài),如果相隔幾秒查詢一次,URL不變的話,顯示出來的狀態(tài)永遠(yuǎn)不會改變,因?yàn)闉g覽器第一次獲取了內(nèi)容之后就不再更新了。
    為了解決這個問題,最簡單的辦法就是在URL后面加上一個不斷改變的查詢字符串(query string),例如:
    request.jsp?q=q&date=(new Date()).getTime()
    紅色部分就是不斷改變的查詢字符串。

    感謝http://wangcheng.javaeye.com/blog/135887的提示

    http://batmanwl.blog.sohu.com/71841783.html這里還可以看到多種解決方案
    posted @ 2008-02-26 10:33 amp@java 閱讀(812) | 評論 (1)編輯 收藏

    通過JavaME的WMA可選包發(fā)送短信時,手機(jī)會提示是否允許程序發(fā)送該短信,雖然不太影響應(yīng)用,但每次都要按一下允許也很不爽。從網(wǎng)上看到有人說對jar包簽名后就不會出現(xiàn)這種情況了,但是簽名的證書要向兩個大公司買,因?yàn)槭謾C(jī)里面一般只內(nèi)置了那兩個大公司的根證書,而且手機(jī)不允許安裝新的根證書,這不分明是圈錢嗎?不知道當(dāng)初制定這個標(biāo)準(zhǔn)的家伙收了那兩個公司多少黑錢!雖然這樣會使很多病毒不能運(yùn)行,但是那兩個公司又不是上帝,給錢就可以買到證書了,他們又沒什么力量也不會去研究購買證書的人要干什么,如果有惡意的人只要花點(diǎn)錢,同樣可以造出帶簽名的病毒來。
    但是辦法總是有的,有人另辟蹊徑,通過非常手段給手機(jī)安裝一個自己制作的根證書。詳細(xì)過程可以看這里:http://browndrf.blogspot.com/,原理就是利用了NOKIA某些型號的手機(jī)可以通過web下載證書并安裝的漏洞。我實(shí)驗(yàn)了一下,整個過程其實(shí)不用那么復(fù)雜,不需要用到NOKIA的簽名工具,直接用SUN WTK的簽名工具就可以了,也不需要通過網(wǎng)絡(luò)安裝程序,跟平時安裝沒簽名的程序一樣。
    然而,簽了名的程序同樣需要確認(rèn)才能發(fā)送短信!而且比沒簽名的程序更麻煩,還要在MIDLet-Permissions里面填上一大堆許可,不簽名的軟件這個項(xiàng)根本不用填。唯一的好處是安裝的時候不會提示程序不受信任,而且不能用無簽名的同名程序覆蓋。但是這種安裝過程的問題并不需要多大關(guān)注,因?yàn)榘惭b只是很少的時間,關(guān)鍵是使用。
    后來在這里:http://blog.csdn.net/zhengyun_ustc/archive/2006/04/07/654226.aspx又發(fā)現(xiàn)一篇文章,說明能夠安裝根證書的不過是個別機(jī)型的漏洞,是不符合MIDP 2.0安全標(biāo)準(zhǔn)的,算了,這個問題還是沒法解決,死心!
    JavaME真的有點(diǎn)像雞肋,它最大的優(yōu)點(diǎn)是跨平臺,但各種手機(jī)的支持程度又各不相同,一點(diǎn)點(diǎn)小的差異就搞得人暈頭轉(zhuǎn)向。而且各種各樣的限制使得它最多就弄點(diǎn)小游戲玩玩,要連接網(wǎng)絡(luò)還得一堆的許可,程序大了還容易莫名其妙地崩潰。真是食之無味,棄之可惜。
    可是,我還是要搞……
    posted @ 2008-02-01 18:41 amp@java 閱讀(332) | 評論 (0)編輯 收藏

    Bouncy Castle(http://www.bouncycastle.org/)是一個龐大的加密類庫,支持Java和C#,其中Java部分發(fā)布的源代碼壓縮包就有24M左右,支持JDK 1.0~5.0,支持J2ME(現(xiàn)在叫JavaME)。
    但是,這個類庫使用起來并不那么方便,它并沒有與普通Java類庫那樣以Jar形式發(fā)布立即可用的二進(jìn)制類庫,而只發(fā)布源代碼,源代碼包含了多份,包括JDK1.0,JDK1.1,JDK1.2,JDK1.3,JDK1.4,JDK1.5,J2ME等,每種環(huán)境都有少量文件不一樣,有多個用于Ant的build xml,分別用于各種不同的JDK,但是每個xml定義了多個target,不知道哪個target才能build出可用的類庫來,選中了其中某個target有可能會出現(xiàn)錯誤,build不下去。文檔太簡單,基本沒講到怎么生成可用的類庫,網(wǎng)上的相關(guān)文檔也很少。我嘗試了兩天才終于把第一個MIDP加密測試程序運(yùn)行成功。
    我的應(yīng)用只是實(shí)現(xiàn)Java ME的加密,所以這里講的只是針對JavaME的,JavaSE應(yīng)該會簡單一點(diǎn)。

    打開下載下來的壓縮包(crypto-138.zip),會發(fā)現(xiàn)里面有一堆文件夾和一堆文件,其中一個文件夾叫j2me,于是第一反應(yīng)就是打開它看看里面是什么,發(fā)現(xiàn)里面只有少量的源代碼文件,看來這只是適用于j2me的一部分源代碼而已,其他通用的部分不在這里。
    還有一個j2me.xml,是一個Ant的build文件,在eclipse里面用ant打開以后,發(fā)現(xiàn)里面有很多target,除了what(輸出一些信息)和init(建立幾個目錄,復(fù)制一些文件)這兩個能執(zhí)行成功之外,其他幾乎都是失敗的,所以通過這個東西是搞不出我們可用的classes來的。
    沒辦法,只有一個個目錄地看,在一個zips目錄里面發(fā)現(xiàn)cldc_sources.zip,里面的源代碼文件有很多,有點(diǎn)像了,于是就把它解壓后放到一個Eclipse ME測試項(xiàng)目的src目錄下,找到org.bouncycastle.crypto.examples包,里面有個MIDPTest.java文件,還有個midp_test.jad,看來這個是用來測試用的MIDP了,調(diào)出WTK的模擬器來運(yùn)行一下,果然是,成功了。
    下一步是在手機(jī)上運(yùn)行。如果不混淆,生成的JAR包有1.6M之巨,不管了,先試一下。安裝到手機(jī)上,到最后出現(xiàn)“授權(quán)失敗”的提示,安裝不成功。記起原來找文檔時在index.html里面看到有這么一句話:The final caveat to this is that as the j2me distribution includes some compatibility classes starting in the java package, you need to use an obfuscator to change the package names before attempting to import a midlet using the BC API. 似乎因?yàn)橛糜趈2me的版本有幾個以java開頭的包,里面包含了一些兼容類,可能是用于補(bǔ)充CLDC的不足,由于java開頭的包是系統(tǒng)包,是不允許修改的,所以不處理過的話安裝會失敗。必須先用混淆器弄一下才行。Eclipse ME配置混淆器十分簡單,我使用的是ProGuard。參照http://www.cnjm.net/eclipseme/docs/configuring.html配置即可。然后運(yùn)行Create Obfuscated Package生成混淆過的包,只有13K。安裝在Nokia 6681上,成功,運(yùn)行,也成功了。嘗試修改一下MIDPTest.java,在whichCipher方法里面,把返回值改為其他數(shù)字(0-4),就可以修改加密方式,但是由于DES加密使用的密鑰長度為64bit,而默認(rèn)的key是"0123456789abcdef0123456789abcdef",運(yùn)行DES是會提示密鑰太長,我開始以為把key改為4個字符就可以(因?yàn)镴ava使用Unicode,每個字符2字節(jié),4個字符8字節(jié)=64bit),卻出現(xiàn)了數(shù)組越界的異常,其實(shí)這個key并不是直接用作密鑰,還要經(jīng)過處理的。嘗試了8個字符也不行,最后發(fā)現(xiàn)16個字符就可以了,應(yīng)該是每兩個字符對應(yīng)一個16進(jìn)制數(shù)。測試程序是對“www.bouncycastle.org”這個字符串進(jìn)行加密和解密,速度還是挺快的,幾乎感覺不到需要時間(在手機(jī)上啟動Java程序本來就比較慢)。

    中間還碰到一個問題,由于我是把源代碼直接復(fù)制到一個原來建立好的MIDP項(xiàng)目里,那個MIDP項(xiàng)目里已經(jīng)有個默認(rèn)的JAD文件,但是里面沒有表示要運(yùn)行的Midlet,生成Jar包之后,安裝到手機(jī)上到最后會出現(xiàn)安裝文件無效的提示。打開那個JAD文件,在Midlets標(biāo)簽里點(diǎn)擊Add按鈕,把org.bouncycastle.crypto.examples.MIDPTest添加進(jìn)去即可。

    以上測試使用的環(huán)境是:
    JDK 1.5.02
    Eclipse 3.2.0
    Eclipse ME 1.7.7 http://eclipseme.org
    Sun WTK 2.5.2 for CLDC
    ProGuard 4.1 http://proguard.sourceforge.net/



    剛剛發(fā)現(xiàn)Bouncy Castle的下載頁面http://www.bouncycastle.org/latest_releases.html里面有專用于J2ME的源代碼發(fā)行包,里面只包含用于J2ME的代碼,如果僅用在J2ME下的話,這個應(yīng)該比較簡單,不用找半天。
    posted @ 2008-01-25 19:59 amp@java 閱讀(1448) | 評論 (1)編輯 收藏

    有時候我們需要通過程序自動發(fā)送一些純文字的信息,通過SMS可以達(dá)到目的,但當(dāng)文字達(dá)到一定長度時,就必須分割成多條短信(一般60漢字一條),增加了費(fèi)用,通過MMS可以解決這一問題,MMS最大支持100KB的內(nèi)容,假設(shè)每個漢字3byte(使用UTF-8編碼),能發(fā)送33K個漢字,一次可以發(fā)送一篇文章了。
    Now SMS/MMS提供了一個Web界面用于發(fā)送彩信,通過Apache HttpClient,我們可以模擬瀏覽器的行為向web服務(wù)器提交表單,發(fā)送彩信。Now SMS/MMS的Web界面提供了很多選項(xiàng),但發(fā)送純文字彩信的話我們只需要填寫接收者,主題(可選),內(nèi)容即可,把對應(yīng)的表單內(nèi)容POST到當(dāng)前頁面,就能發(fā)送一條彩信。(待續(xù))
    posted @ 2007-10-01 14:22 amp@java 閱讀(1162) | 評論 (0)編輯 收藏

    Now SMS/MMS是一個強(qiáng)大的短信/彩信發(fā)送服務(wù)器,它內(nèi)置了彩信中心,在某些運(yùn)營商的網(wǎng)絡(luò)內(nèi)可以通過普通的短信貓發(fā)送彩信,而不需要使用支持GPRS的短信貓,也就是說系統(tǒng)本身就具有了運(yùn)營商的彩信中心的功能。然而,在中國移動的網(wǎng)絡(luò)內(nèi)是不能實(shí)現(xiàn)這種方式發(fā)送彩信的,必須通過移動夢網(wǎng)的彩信中心轉(zhuǎn)發(fā)。
    彩信的發(fā)送其實(shí)是兩個過程:
    1、向目標(biāo)手機(jī)發(fā)送一條普通的提醒短信,其中包含了發(fā)送者號碼、彩信的URL等信息,該URL指向彩信中心的某個web目錄下的某個彩信文件;
    2、目標(biāo)手機(jī)接收到這條提醒短信后,主動發(fā)起GPRS連接,根據(jù)短信中的URL向彩信中心提取該彩信,并顯示出來。
    Now SMS/MMS 自帶的彩信中心其實(shí)就是一個支持手機(jī)連接的web服務(wù)器,它把制作好的彩信放在某個web目錄下,手機(jī)連接時就可以下載。
    然而,實(shí)踐證明,如果使用中國移動的SIM卡,無論使用的是什么短信貓,都不能通過系統(tǒng)自帶的彩信中心發(fā)送彩信。
    要設(shè)置成通過移動公司的彩信中心發(fā)送彩信,必須把系統(tǒng)的默認(rèn)設(shè)置——使用自帶的MMSC(彩信中心)——改為使用移動公司的MMSC。方法如下:
    在Now SMS/MMS Gateway配置程序中選擇MMSC Routing,然后點(diǎn)擊Add按鈕,在彈出的對話框中建立一個新的MMSC配置,其中Acount Name和Account Description可以隨便填,只是用來識別配置名稱,因?yàn)橄到y(tǒng)可以設(shè)置多個MMSC。Default Sender Address必須留空,否則發(fā)送很難成功(有極少部分能夠發(fā)送成功)。Allow Sender Address Override前的復(fù)選框也必須留空。Route messages to this account for recipient phone number(s)不用填(這是一個掩碼,只有符合要求的號碼才用這個路由,按照官方文檔的說法,不填的話是不會用這個路由的,但實(shí)際上把它設(shè)成默認(rèn)路由的話,即使不填也會用這個,也許填上+861*,1*會好些,表示中國的手機(jī)都用這個發(fā))。Route messages to VASP via選擇MM1,之后會出現(xiàn)更多的輸入框,點(diǎn)擊Look up Operator Seetings,出現(xiàn)一個選擇運(yùn)營商的對話框,很幸運(yùn),中國移動在里面,選擇China - China Mobile,然后OK即可,系統(tǒng)自動把適合中國移動的內(nèi)容填了進(jìn)去。但是Network Connection和Modem Used兩個下拉列表還沒選好。這里必須使用對應(yīng)的GPRS貓的調(diào)制解調(diào)器(在控制面板-電話和調(diào)制解調(diào)器選項(xiàng)-調(diào)制解調(diào)器-添加,按照提示一步步就能找到GPRS貓,看好哪個調(diào)制解調(diào)器對應(yīng)哪個端口,從而知道哪個調(diào)制解調(diào)器對應(yīng)哪個GPRS貓)。填好這些東西后點(diǎn)擊Test Connection可以檢測連接,成功就可以了,檢測時間比較長,要耐心等待。填好之后點(diǎn)擊OK,在MMSC Routing標(biāo)簽頁里的Additional Routes里面就能看到剛才的那個配置名稱,然后在Default Route里面選擇剛才的配置名稱作為默認(rèn)路由就可以了。
    之后打開MMSC標(biāo)簽,配置自帶的MMSC。雖然我們使用的是中國移動的MMSC,但通過web發(fā)送彩信時,必須先發(fā)送到系統(tǒng)自帶的MMSC,再轉(zhuǎn)發(fā)到移動的MMSC,所以必須把系統(tǒng)的MMSC也配置好。這里就是普通web服務(wù)器的配置(還有SMTP的配置,可選),把端口和IP選好后,還要注意Local Host Name or IP Address里要填入一個本機(jī)的IP,如果在僅在內(nèi)網(wǎng)使用,可以直接填本機(jī)IP(外網(wǎng)的情況沒有研究過,看看說明書先)。其他默認(rèn)的就可以了。
    再打開Web標(biāo)簽頁,把Web服務(wù)器配置好。
    打開瀏覽器,輸入http://服務(wù)器IP:web服務(wù)器端口/,就能看到發(fā)送各種短信、彩信的鏈接,然后就可以發(fā)送彩信進(jìn)行測試了。如果發(fā)送不成功,可以打開Serial #標(biāo)簽頁,把底下的三個Debug選項(xiàng)都勾上,再發(fā)送一下,然后在Now SMS/MMS 的安裝目錄下找到MMSCDEBUG.LOG等幾個LOG文件查看究竟是什么問題。文件太大會導(dǎo)致發(fā)送失敗,系統(tǒng)不會自動檢查的。文件大小的上限還不清楚,但超過100KB似乎就肯定不行。
    今天搞了一天這個東西,終于能正常發(fā)送彩信了。在這里備忘一下。慢慢再作深入研究。


    感謝:http://blog.csdn.net/phiger/archive/2006/12/19/1449176.aspx

    官方文檔:http://www.nowsms.com/documentation/ProductDocumentation/mms_notifications_and_content/Connecting_to_operator_MMSC.htm#SendingMMSMessages
    posted @ 2007-09-18 19:32 amp@java 閱讀(5407) | 評論 (18)編輯 收藏

    一個使用了JSTL的JSP頁面,當(dāng)字符集設(shè)為GB18030時,總會隨機(jī)的出現(xiàn)一些亂碼,莫名其妙的,有時候有,有時候沒有,刷新一下可能會變,也可能不變;最令人懊惱的是,利用JSTL生成的JavaScript語句經(jīng)常會漏掉一兩個字母,害得整個JS程序段出錯,每次漏的字目都不一樣,根本沒法改。
    似乎google搜不到相關(guān)信息,沒辦法,后來把編碼改為UTF-8,就不會再出現(xiàn)這種情況了,但不知道以后還會不會出現(xiàn)。
    有時候上網(wǎng)易,也會見到一些字符出現(xiàn)亂碼,刷新一下就沒有了,看來這是JSP的通病,為什么就沒有人提出解決方案呢?
    posted @ 2007-09-10 19:48 amp@java 閱讀(1361) | 評論 (7)編輯 收藏

    通過JDBC-ODBC橋連接某個ACCESS數(shù)據(jù)庫,并把一個逗號分隔文本文件插入到某個表中,如果插入過程中沒有其他程序使用該數(shù)據(jù)庫,只需要20多秒就可以完成;如果插入的同時,還用ACCESS程序打開了那個mdb文件,雖然沒有任何操作,但運(yùn)行相同的插入程序,竟然需要80多秒,性能下降4倍!!
    ACCESS=垃圾!
    posted @ 2007-07-15 02:15 amp@java 閱讀(1499) | 評論 (0)編輯 收藏

    使用AVG,SUM等SQL聚合函數(shù)在Access查詢,速度慢得要命,7個整數(shù)的求和或平均居然要幾秒才能算出來;通過JDBC連接,把數(shù)據(jù)查出來后再自己求和或求平均,速度不知道要快多少。
    奇怪,不知道Access是怎么搞的,求平均可能因?yàn)楦↑c(diǎn)運(yùn)算慢,但整數(shù)求和為什么也會慢呢?
    posted @ 2007-07-09 22:26 amp@java 閱讀(1572) | 評論 (3)編輯 收藏

    主站蜘蛛池模板: 亚洲人成网站看在线播放| 日韩毛片免费无码无毒视频观看| 久久精品国产亚洲精品| 老司机午夜在线视频免费观| 日产乱码一卡二卡三免费| 亚洲欧好州第一的日产suv| 国产成人免费爽爽爽视频| 亚洲永久在线观看| 国产桃色在线成免费视频| 亚洲一级毛片免费看| 欧洲一级毛片免费| 亚洲伊人色一综合网| 波多野结衣免费在线| 亚洲人成7777| 成年人网站在线免费观看| 亚洲依依成人亚洲社区| 在线观看免费成人| 亚洲AV无码成人精品区日韩 | 久久亚洲日韩精品一区二区三区| 日本免费大黄在线观看| 亚洲视频在线免费播放| 国产2021精品视频免费播放| 久久精品国产亚洲αv忘忧草| 成人毛片手机版免费看| 亚洲av无码一区二区三区在线播放| 免费jjzz在线播放国产 | 亚洲精品视频免费观看| 99精品全国免费观看视频..| 亚洲gv猛男gv无码男同短文| 99久久99久久精品免费观看| 亚洲国产精品午夜电影| 久久精品a一国产成人免费网站| 亚洲av乱码一区二区三区按摩| 亚洲国产成人精品无码久久久久久综合| 一级做α爱过程免费视频| 国产亚洲高清不卡在线观看| 50岁老女人的毛片免费观看| 456亚洲人成在线播放网站| 午夜网站免费版在线观看| 一边摸一边爽一边叫床免费视频 | 亚洲精品无码午夜福利中文字幕|