隨筆 - 35  文章 - 21  trackbacks - 0
          <2010年2月>
          31123456
          78910111213
          14151617181920
          21222324252627
          28123456
          78910111213

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          文章分類

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          1 Launch Keychain Access from your local Mac and from the login keychain, filter by the Certificates category. You will see an expandable option called “Apple Development Push Services”
          2 Right click on “Apple Development Push Services” > Export “Apple Development Push Services ID123″. Save this as apns-dev-cert.p12 file somewhere you can access it. There is no need to enter a password.
          3 The next command generates the cert in Mac’s Terminal for PEM format (Privacy Enhanced Mail Security Certificate):
          openssl pkcs12 -in apns-dev-cert.p12 -out apns-dev-cert.pem -nodes -clcerts
          posted @ 2012-05-29 11:07 lincode 閱讀(733) | 評(píng)論 (0)編輯 收藏

          這個(gè) bug 在 xcode 4.3 以下會(huì)出現(xiàn),4.3 以后已經(jīng)修正了。
          解決方法為:找到 target 的圖標(biāo),更改其 Other Linker Flags 為: -all_load 或 -force_load
          -force_load,后跟隨一個(gè)文件位置,可以更精確地加載所需文件。
           
          蘋果的解釋為 : http://developer.apple.com/library/mac/#qa/qa1490/_index.html

          簡(jiǎn)單點(diǎn)說就是,Objective-C 的動(dòng)態(tài)特性使得需要,為鏈接器添加一個(gè)標(biāo)簽(設(shè)置 Other Linker Flags 為 -ObjC)來解決通過 Category 向類添加方法的問題。
          但這個(gè)標(biāo)簽 -ObjC 在 64 位 和 iOS 中有問題,需要使用 -all_load 或 -force_load。

          總結(jié)如下:
          如果,第三庫(kù)中沒有 category,Other Linker Flags 無需設(shè)置
          如果,第三方庫(kù)中有 category,需要設(shè)置為 -ObjC
          如果,某些 Xcode 版本中,出現(xiàn)問題,修改設(shè)置為 -all_load
          posted @ 2012-04-23 14:56 lincode 閱讀(1814) | 評(píng)論 (0)編輯 收藏
          獲得 Crash Report:
          1 itunesConnect 的后臺(tái)會(huì)提供一個(gè) Crash report 表;
          2 把一臺(tái)打開了開發(fā)模式的機(jī)器接入 Mac,Xcode 的 Organizer 中能查看這臺(tái)設(shè)備的 Crash Report;
          3 若使用了 Umeng.com, Bugsense.com 之類的工具。

          閱讀 Crash Report:
          這之前需要一個(gè)名為 AppName.app.dSYM 的文件。Xcode 中,Archive 一個(gè)項(xiàng)目之后,可以在 Organizer 的 Archives 分頁(yè)中,找到所有項(xiàng)目的 Archvie 文件。
          右鍵點(diǎn)擊一個(gè), Show Package Content,就能看到一個(gè)類似 AppName-3-19-12.app.PM.xcarchive  的文件,show in finder 這個(gè)文件,就能找到 .dSYM 文件。

          在 Ternimal 中執(zhí)行,若是 來自于 iphone 3G 的機(jī)器,就需要使用 armv6 代替 armv7.

           atos -o AppName.app.dSYM/Contents/Resources/DWARF/AppName  -arch armv7 0x0000b82

          這樣就能看到,地址對(duì)應(yīng)的類,函數(shù),代碼行數(shù)。這個(gè)命令只能解析出客戶代碼的位置。若是錯(cuò)誤堆棧中的系統(tǒng)調(diào)用,是無法翻譯出來的。
          posted @ 2012-03-18 13:56 lincode 閱讀(1002) | 評(píng)論 (0)編輯 收藏
          Apple 提供了一個(gè)地址方向解析的服務(wù) MKReverseGeocoder,上傳一個(gè)經(jīng)緯度,返回一個(gè)詳細(xì)的地理位置信息。但這個(gè)服務(wù)在中國(guó)不太穩(wěn)定,時(shí)常不可用。
          Google map 也提供了一個(gè)類似的服務(wù),是訪問一個(gè) google map 的 api,這里試圖封裝了 google map 的服務(wù)。使使用 apple 和 google 的服務(wù)的接口基本一致,替換起來很容易。Google map 的這個(gè)服務(wù)在中國(guó)的狀態(tài)比 apple 稍微好一些,但也有不穩(wěn)定的時(shí)候。我猜想,apple 也許是使用 google 的服務(wù)封裝了自己的 MKReverseGeocoder。若是如此,這里的嘗試也就沒有什么意義了。

          DOUHttpRequest 是對(duì) ASIHTTPRequest 的一個(gè)簡(jiǎn)單封裝。這些代碼可以 繼承自 MKReverseGeocoder。這樣,使用方法就和 MKReverseGeocoder 一樣了。

          static NSString* kGeoServerUrl = @"http://maps.google.com/maps/api/geocode/json?latlng=%f,%f&sensor=true&language=en";
          static NSString* kLatitudeUserInfoKey = @"latitudeUserInfoKey";
          static NSString* kLongitudeUserInfoKey = @"longitudeUserInfoKey";

          //
          // It's tje solution for replacing MKReverseGeocoder that has problem in China.
          //
          - (void)startedReverseGeoderWithLatitude:(double)latitude longitude:(double)longitude {
            NSString *url = [NSString stringWithFormat:kGeoServerUrl, latitude, longitude];
            DOUHttpRequest *req = [DOUHttpRequest requestWithURL:[NSURL URLWithString:url] target:self];
            
            NSNumber *lat = [NSNumber numberWithDouble:latitude];
            NSNumber *lon = [NSNumber numberWithDouble:longitude];
            req.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:lat, kLatitudeUserInfoKey, lon, kLongitudeUserInfoKey, nil];
            
            DOUService *service = [DOUService sharedInstance];  
            [service addRequest:req];
          }


          - (NSDictionary *)addressDictionary:(NSObject *)obj {
            
            NSArray* ary = nil;
            if (IS_INSTANCE_OF(obj, NSDictionary)) {
              NSObject* data = [(NSDictionary*)obj objectForKey:@"results"];
              if (IS_INSTANCE_OF(data, NSArray)) {
                ary = (NSArray*)data;
                NSDictionary *dic = [ary objectAtIndex:0];
                
                NSArray *addressComps = [dic objectForKey:@"address_components"];
                
                //NSString *streetNumber = @"";
                NSString *route = @"";
                NSString *locality = @"";
                NSString *country = @"";
                for (NSDictionary *comp in addressComps) {
                  NSArray *types = [comp objectForKey:@"types"];
                  NSString *type = [types objectAtIndex:0];
                  
          //        if ([type isEqualToString:@"street_number"]) {
          //          streetNumber = [comp objectForKey:@"long_name"];
          //        }
                  
                  if ([type isEqualToString:@"route"]) {
                    route = [comp objectForKey:@"long_name"];
                  }
                  
                  if ([type isEqualToString:@"locality"]) {
                    locality = [comp objectForKey:@"long_name"];
                  }
                  
                  if ([type isEqualToString:@"country"]) {
                    country = [comp objectForKey:@"long_name"];
                  }        
                }
                
                NSDictionary *addressDic = [NSDictionary dictionaryWithObjectsAndKeys:route, kABPersonAddressStreetKey,
                                            locality, kABPersonAddressCityKey,                                        
                                            country, kABPersonAddressCountryKey, nil];
                return addressDic;
              }
            }
            return nil;
          }


          - (void)requestFinished:(DOUHttpRequest *)req {
            NSError *error = [req error];
            if (!error) {
              DebugLog(@"str:%@", [req responseString]);
              
              NSObject *obj = [[req responseString] JSONValue];
              NSDictionary *addressDic = [self addressDictionary:obj];
              
              CLLocationCoordinate2D coordinate;
              coordinate.latitude = [[req.userInfo objectForKey:kLatitudeUserInfoKey] doubleValue];
              coordinate.longitude = [[req.userInfo objectForKey:kLongitudeUserInfoKey] doubleValue]; 
              MKPlacemark *placemark = [[[MKPlacemark alloc] initWithCoordinate:coordinate 
                                                             addressDictionary:addressDic] autorelease];
              [self reverseGeocoder:nil didFindPlacemark:placemark];
            }
          }

          - (void)requestFailed:(DOUHttpRequest *)req { 
            [self reverseGeocoder:nil didFailWithError:[req error]];
          }


          #pragma mark - MKReverseGeocoderDelegate

          static NSString * const AppleLanguagesKey = @"AppleLanguages";

          - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {

            NSArray *array = [[NSUserDefaults standardUserDefaults] objectForKey:AppleLanguagesKey];
            NSString *currentLanguage = [array objectAtIndex:0];
            
            // set current language as english
            [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"zh-Hans", nil] 
                                                      forKey:AppleLanguagesKey];
            NSString *local = [placemark.locality lowercaseString];
           
            [AppContext sharedInstance].currentCityUid = local;
            
            // reset current language
            [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:currentLanguage, nil] 
                                                      forKey:AppleLanguagesKey];
          }

          - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {
            TraceLog(@"reverseGeocoder :%@", [error localizedDescription]);  
          }
          posted @ 2012-01-12 21:27 lincode 閱讀(1369) | 評(píng)論 (0)編輯 收藏

          定義

          OAuth(開放授權(quán))是一個(gè)開放標(biāo)準(zhǔn),允許用戶讓第三方應(yīng)用訪問該用戶在某一網(wǎng)站上存儲(chǔ)的私密的資源(如照片,視頻,聯(lián)系人列表),而無需將用戶名和密碼提供給第三方應(yīng)用。

          OAuth允許用戶提供一個(gè)令牌,而不是用戶名和密碼來訪問他們存放在特定服務(wù)提供者的數(shù)據(jù)。每一個(gè)令牌授權(quán)一個(gè)特定的網(wǎng)站(例如,視頻編輯網(wǎng)站)在特定的時(shí)段(例如,接下來的2小時(shí)內(nèi))內(nèi)訪問特定的資源(例如僅僅是某一相冊(cè)中的視頻)。這樣,OAuth允許用戶授權(quán)第三方網(wǎng)站訪問他們存儲(chǔ)在另外的服務(wù)提供者上的信息,而不需要分享他們的訪問許可或他們數(shù)據(jù)的所有內(nèi)容。



          認(rèn)證和授權(quán)過程


          在認(rèn)證和授權(quán)的過程中涉及的三方包括:
          • 服務(wù)提供方,用戶使用服務(wù)提供方來存儲(chǔ)受保護(hù)的資源,如照片,視頻,聯(lián)系人列表。
          • 用戶,存放在服務(wù)提供方的受保護(hù)的資源的擁有者。
          • 客戶端,要訪問服務(wù)提供方資源的第三方應(yīng)用,通常是網(wǎng)站,如提供照片打印服務(wù)的網(wǎng)站。在認(rèn)證過程之前,客戶端要向服務(wù)提供者申請(qǐng)客戶端標(biāo)識(shí)。

          使用OAuth進(jìn)行認(rèn)證和授權(quán)的過程如下所示:

          1. 用戶訪問客戶端的網(wǎng)站,想操作用戶存放在服務(wù)提供方的資源。
          2. 客戶端服務(wù)提供方請(qǐng)求一個(gè)臨時(shí)令牌。
          3. 服務(wù)提供方驗(yàn)證客戶端的身份后,授予一個(gè)臨時(shí)令牌。
          4. 客戶端獲得臨時(shí)令牌后,將用戶引導(dǎo)至服務(wù)提供方的授權(quán)頁(yè)面請(qǐng)求用戶授權(quán)。在這個(gè)過程中將臨時(shí)令牌和客戶端的回調(diào)連接發(fā)送給服務(wù)提供方
          5. 用戶服務(wù)提供方的網(wǎng)頁(yè)上輸入用戶名和密碼,然后授權(quán)該客戶端訪問所請(qǐng)求的資源。
          6. 授權(quán)成功后,服務(wù)提供方引導(dǎo)用戶返回客戶端的網(wǎng)頁(yè)。
          7. 客戶端根據(jù)臨時(shí)令牌從服務(wù)提供方那里獲取訪問令牌。
          8. 服務(wù)提供方根據(jù)臨時(shí)令牌和用戶的授權(quán)情況授予客戶端訪問令牌。
          9. 客戶端使用獲取的訪問令牌訪問存放在服務(wù)提供方上的受保護(hù)的資源。


          OAuth 2.0

          OAuth 2.0是OAuth協(xié)議的下一版本,但不向后兼容OAuth 1.0。 OAuth 2.0關(guān)注客戶端開發(fā)者的簡(jiǎn)易性,同時(shí)為Web應(yīng)用,桌面應(yīng)用和手機(jī),和起居室設(shè)備提供專門的認(rèn)證流程。規(guī)范還在IETF OAuth工作組的開發(fā)中 ,按照Eran Hammer-Lahav的說法,OAuth將于2010年末完成。

          Facebook的新的Graph API只支持OAuth 2.0,Google在2011年3月亦宣佈Google API對(duì)OAuth 2.0的支援。

          posted @ 2011-10-27 18:15 lincode 閱讀(324) | 評(píng)論 (0)編輯 收藏

          名稱

          REST,即Representational State Transfer的縮寫。我對(duì)這個(gè)詞組的翻譯是"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。

          如果一個(gè)架構(gòu)符合REST原則,就稱它為RESTful架構(gòu)。

          要理解RESTful架構(gòu),最好的方法就是去理解Representational State Transfer這個(gè)詞組到底是什么意思,它的每一個(gè)詞代表了什么涵義。如果你把這個(gè)名稱搞懂了,也就不難體會(huì)REST是一種什么樣的設(shè)計(jì)。

          資源(Resources)

          REST的名稱"表現(xiàn)層狀態(tài)轉(zhuǎn)化"中,省略了主語(yǔ)。"表現(xiàn)層"其實(shí)指的是"資源"(Resources)的"表現(xiàn)層"。

          所謂"資源",就是網(wǎng)絡(luò)上的一個(gè)實(shí)體,或者說是網(wǎng)絡(luò)上的一個(gè)具體信息。它可以是一段文本、一張圖片、一首歌曲、一種服務(wù),總之就是一個(gè)具體的實(shí)在。你可以用一個(gè)URI(統(tǒng)一資源定位符)指向它,每種資源對(duì)應(yīng)一個(gè)特定的URI。要獲取這個(gè)資源,訪問它的URI就可以,因此URI就成了每一個(gè)資源的地址或獨(dú)一無二的識(shí)別符。

          所謂"上網(wǎng)",就是與互聯(lián)網(wǎng)上一系列的"資源"互動(dòng),調(diào)用它的URI。

          表現(xiàn)層(Representation)

          "資源"是一種信息實(shí)體,它可以有多種外在表現(xiàn)形式。我們把"資源"具體呈現(xiàn)出來的形式,叫做它的"表現(xiàn)層"(Representation)。

          比如,文本可以用txt格式表現(xiàn),也可以用HTML格式、XML格式、JSON格式表現(xiàn),甚至可以采用二進(jìn)制格式;圖片可以用JPG格式表現(xiàn),也可以用PNG格式表現(xiàn)。

          URI只代表資源的實(shí)體,不代表它的形式。嚴(yán)格地說,有些網(wǎng)址最后的".html"后綴名是不必要的,因?yàn)檫@個(gè)后綴名表示格式,屬于"表現(xiàn)層"范疇,而URI應(yīng)該只代表"資源"的位置。它的具體表現(xiàn)形式,應(yīng)該在HTTP請(qǐng)求的頭信息中用Accept和Content-Type字段指定,這兩個(gè)字段才是對(duì)"表現(xiàn)層"的描述。

          狀態(tài)轉(zhuǎn)化(State Transfer)

          訪問一個(gè)網(wǎng)站,就代表了客戶端和服務(wù)器的一個(gè)互動(dòng)過程。在這個(gè)過程中,勢(shì)必涉及到數(shù)據(jù)和狀態(tài)的變化。

          互聯(lián)網(wǎng)通信協(xié)議HTTP協(xié)議,是一個(gè)無狀態(tài)協(xié)議。這意味著,所有的狀態(tài)都保存在服務(wù)器端。因此,如果客戶端想要操作服務(wù)器,必須通過某種手段,讓服務(wù)器端發(fā)生"狀態(tài)轉(zhuǎn)化"(State Transfer)。而這種轉(zhuǎn)化是建立在表現(xiàn)層之上的,所以就是"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。

          客戶端用到的手段,只能是HTTP協(xié)議。具體來說,就是HTTP協(xié)議里面,四個(gè)表示操作方式的動(dòng)詞:GET、POST、PUT、DELETE。它們分別對(duì)應(yīng)四種基本操作:GET用來獲取資源,POST用來新建資源(也可以用于更新資源),PUT用來更新資源,DELETE用來刪除資源。

          綜述

          綜合上面的解釋,我們總結(jié)一下什么是RESTful架構(gòu):

           ?。?)每一個(gè)URI代表一種資源;

           ?。?)客戶端和服務(wù)器之間,傳遞這種資源的某種表現(xiàn)層;

            (3)客戶端通過四個(gè)HTTP動(dòng)詞,對(duì)服務(wù)器端資源進(jìn)行操作,實(shí)現(xiàn)"表現(xiàn)層狀態(tài)轉(zhuǎn)化"。

          誤區(qū)

          RESTful架構(gòu)有一些典型的設(shè)計(jì)誤區(qū)。

          最常見的一種設(shè)計(jì)錯(cuò)誤,就是URI包含動(dòng)詞。因?yàn)?資源"表示一種實(shí)體,所以應(yīng)該是名詞,URI不應(yīng)該有動(dòng)詞,動(dòng)詞應(yīng)該放在HTTP協(xié)議中。

          舉例來說,某個(gè)URI是/posts/show/1,其中show是動(dòng)詞,這個(gè)URI就設(shè)計(jì)錯(cuò)了,正確的寫法應(yīng)該是/posts/1,然后用GET方法表示show。

          如果某些動(dòng)作是HTTP動(dòng)詞表示不了的,你就應(yīng)該把動(dòng)作做成一種資源。比如網(wǎng)上匯款,從賬戶1向賬戶2匯款500元,錯(cuò)誤的URI是:

            POST /accounts/1/transfer/500/to/2

          正確的寫法是把動(dòng)詞transfer改成名詞transaction,資源不能是動(dòng)詞,但是可以是一種服務(wù):

            POST /transaction HTTP/1.1
            Host: 127.0.0.1
            
            from=1&to=2&amount=500.00

          另一個(gè)設(shè)計(jì)誤區(qū),就是在URI中加入版本號(hào)

            http://www.example.com/app/1.0/foo

            http://www.example.com/app/1.1/foo

            http://www.example.com/app/2.0/foo

          因?yàn)椴煌陌姹?,可以理解成同一種資源的不同表現(xiàn)形式,所以應(yīng)該采用同一個(gè)URI。版本號(hào)可以在HTTP請(qǐng)求頭信息的Accept字段中進(jìn)行區(qū)分(參見Versioning REST Services):

            Accept: vnd.example-com.foo+json; version=1.0

            Accept: vnd.example-com.foo+json; version=1.1

            Accept: vnd.example-com.foo+json; version=2.0


          原帖:http://www.ruanyifeng.com/blog/2011/09/restful.html
          posted @ 2011-10-27 18:02 lincode 閱讀(303) | 評(píng)論 (0)編輯 收藏

          PhoneGap 是一個(gè)移動(dòng)開發(fā)框架。通過 PhoneGap,開發(fā)者可以使用 JavaScript 調(diào)用手機(jī)的原生功能,例如,獲取經(jīng)緯度,讓手機(jī)振動(dòng)等。
          主頁(yè) http://www.phonegap.com/ 。
          源碼 https://github.com/phonegap/phonegap-android 。

          PhoneGap 在早期,應(yīng)該是使用 WebView 的 addJavaScriptInterface 方法,來為 JS 提供調(diào)用原生功能可能。addJavaScriptInterface ,可以將一個(gè) Java 對(duì)象綁定到一個(gè) JS 對(duì)象。是的,JS對(duì)象可以調(diào)用 Java方法。但在 PhoneGap 1.0.0 這個(gè)版本中,PhoneGap 改變了方法。

          以振動(dòng)功能為例,我們可以看一下程序調(diào)用的流程:

          1 在 JS 中,啟動(dòng)命令

          main.js / navigator.notification.vibrate(0);

          notification.js / Notification.vibrate.vibrate 中執(zhí)行了 PhoneGap.exec(null, null, "Notification", "vibrate", [mills]);

          phonegap.js / PhoneGap.exc 中執(zhí)行了 var r = prompt(PhoneGap.stringify(args), "gap:"+PhoneGap.stringify([service, action, callbackId, true]));

          這時(shí),WebView 就會(huì)企圖彈出一個(gè)窗口。這時(shí)使用 android 提供的 WebChromeClient 的 API 就可以截獲 WebView 的這個(gè)動(dòng)作 。

          2 JAVA 中,處理命令
          WebView 的 WebChromClient 實(shí)現(xiàn)了下面這個(gè)函數(shù):

          public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)

          在 onJsPrompt 中執(zhí)行了 String r = pluginManager.exec(service, action, callbackId, message, async);

          PlugManager 會(huì)根據(jù)收到參數(shù),將命令分發(fā)給特定的 Plugin。這個(gè)例子中,接收的 plugin 是:Notification。
          落實(shí)到 Notification 的 exec 函數(shù):會(huì)執(zhí)行這一行: this.vibrate(args.getLong(0));

          振動(dòng)的實(shí)現(xiàn)為:

           

           public void vibrate(long time){
                  
          // Start the vibration, 0 defaults to half a second.
                  if (time == 0) {
          time 
          = 500;
          }
                  Vibrator vibrator 
          = (Vibrator) this.ctx.getSystemService(Context.VIBRATOR_SERVICE);
                  vibrator.vibrate(time);
          }

           


          3 Java 處理完后的數(shù)據(jù),需要給 JS 一個(gè)反饋:
          這里 PhoneGap 使用了一個(gè)在客戶端本地實(shí)現(xiàn)的 XHRServer,具體到代碼中就是一個(gè)JAVA 類 CallbackServer。

          分兩個(gè)部分介紹其行為:
          本地 XHRServer,
          思想是,后臺(tái)每執(zhí)行完一個(gè)命令,都會(huì)將結(jié)果存在 CallbackServer 中的一個(gè)鏈表中,具體為CallbackServr的 private LinkedList<String> javascript;
          這個(gè)結(jié)果其實(shí)是一段字符串表示的 JS 函數(shù)調(diào)用。例如檢測(cè)網(wǎng)絡(luò)調(diào)用的結(jié)果為:PhoneGap.callbackSuccess('Network Status1',{status:1,message:"wifi",keepCallback:true});
           XHRServer 的行為很簡(jiǎn)單,只要有請(qǐng)求來,就把鏈表中的最先進(jìn)來的提出來,返回給客戶端。沒有請(qǐng)求來,則 10秒鐘返回一個(gè)空的回復(fù),以維持XHRServer。
          Webview 作為客戶端:
          在 WebView 中,會(huì)有一個(gè)輪詢機(jī)制,這可以參考 PhoneGap.JSCallack 和 PhoneGap.JSCallbackPolling 兩個(gè)函數(shù)來訪問 XHRServer。XHRServer,返回的結(jié)果就是 WebView 需要調(diào)用的 JS 函數(shù)。 在 JS 中,eval() 函數(shù),將返回的結(jié)果變?yōu)橐粋€(gè)可以執(zhí)行的對(duì)象,在 Webview 中執(zhí)行,可以認(rèn)為這即是回調(diào)函數(shù) Callback。這也是為什么 PhoneGap 為何命名 XHRServer 為 CallbackServer 的原因。

          posted @ 2011-09-20 10:20 lincode 閱讀(3743) | 評(píng)論 (1)編輯 收藏
          dip: device independent pixels(設(shè)備獨(dú)立像素)。不同設(shè)備有不同的顯示效果,這個(gè)和設(shè)備硬件有關(guān),一般我們?yōu)榱酥С諻VGA、HVGA和QVGA 推薦使用這個(gè),不依賴像素。 

          dp:(與密度無關(guān)的像素)一種基于屏幕密度的抽象單位。在每英寸160點(diǎn)的顯示器上,1dp = 1px。 

          px: pixels(像素). 不同設(shè)備顯示效果相同,一般我們HVGA代表320x480像素,這個(gè)用的比較多。 

          pt: point(磅),是一個(gè)標(biāo)準(zhǔn)的長(zhǎng)度單位,1pt=1/72英寸,用于印刷業(yè),非常簡(jiǎn)單易用; 

          sp: scaled pixels(放大像素). 主要用于字體顯示best for textsize。 
          posted @ 2011-09-16 17:58 lincode 閱讀(723) | 評(píng)論 (1)編輯 收藏

          android 中自定義的對(duì)象序列化的問題有兩個(gè)選擇一個(gè)是Parcelable,另外一個(gè)是Serializable。

          一 序列化原因:

          1.永久性保存對(duì)象,保存對(duì)象的字節(jié)序列到本地文件中;
          2.通過序列化對(duì)象在網(wǎng)絡(luò)中傳遞對(duì)象;
          3.通過序列化在進(jìn)程間傳遞對(duì)象。 

          二 至于選取哪種可參考下面的原則:

          1.在使用內(nèi)存的時(shí)候,Parcelable 類比Serializable性能高,所以推薦使用Parcelable類。
          2.Serializable在序列化的時(shí)候會(huì)產(chǎn)生大量的臨時(shí)變量,從而引起頻繁的GC。
          3.Parcelable不能使用在要將數(shù)據(jù)存儲(chǔ)在磁盤上的情況,因?yàn)镻arcelable不能很好的保證數(shù)據(jù)的持續(xù)性在外界有變化的情況下。盡管Serializable效率低點(diǎn), 也不提倡用,但在這種情況下,還是建議你用Serializable 。


          實(shí)現(xiàn):
          1 Serializable 的實(shí)現(xiàn),只需要繼承  implements Serializable 即可。這只是給對(duì)象打了一個(gè)標(biāo)記,系統(tǒng)會(huì)自動(dòng)將其序列化。

          2 Parcelabel 的實(shí)現(xiàn),需要在類中添加一個(gè)靜態(tài)成員變量 CREATOR,這個(gè)變量需要繼承 Parcelable.Creator 接口。
          public class MyParcelable implements Parcelable {
               
          private int mData;

               
          public int describeContents() {
                   
          return 0;
               }

               
          public void writeToParcel(Parcel out, int flags) {
                   out.writeInt(mData);
               }

               
          public static final Parcelable.Creator<MyParcelable> CREATOR
                       
          = new Parcelable.Creator<MyParcelable>() {
                   
          public MyParcelable createFromParcel(Parcel in) {
                       
          return new MyParcelable(in);
                   }

                   
          public MyParcelable[] newArray(int size) {
                       
          return new MyParcelable[size];
                   }
               };
               
               
          private MyParcelable(Parcel in) {
                   mData 
          = in.readInt();
               }
           }

           
          posted @ 2011-09-16 16:16 lincode 閱讀(22139) | 評(píng)論 (0)編輯 收藏
          生命周期
          Android 系統(tǒng)在Activity 生命周期中加入一些鉤子,我們可以在這些系統(tǒng)預(yù)留的鉤子中做一些事情。
          例舉了 7 個(gè)常用的鉤子:
          protected void onCreate(Bundle savedInstanceState)
          protected void onStart()
          protected void onResume()
          protected void onPause()
          protected void onStop()
          protected void onRestart()
          protected void onDestroy()

          簡(jiǎn)要說明:
          onCreate(Bundle savedInstanceState):創(chuàng)建activity時(shí)調(diào)用。設(shè)置在該方法中,還以Bundle中可以提出用于創(chuàng)建該 Activity 所需的信息。
          onStart():activity變?yōu)樵谄聊簧蠈?duì)用戶可見時(shí),即獲得焦點(diǎn)時(shí),會(huì)調(diào)用。
          onResume():activity開始與用戶交互時(shí)調(diào)用(無論是啟動(dòng)還是重新啟動(dòng)一個(gè)活動(dòng),該方法總是被調(diào)用的)。
          onPause():activity被暫停或收回cpu和其他資源時(shí)調(diào)用,該方法用于保存活動(dòng)狀態(tài)的。。
          onStop():activity被停止并轉(zhuǎn)為不可見階段及后續(xù)的生命周期事件時(shí),即失去焦點(diǎn)時(shí)調(diào)用。
          onRestart():重新啟動(dòng)activity時(shí)調(diào)用。該活動(dòng)仍在棧中,而不是啟動(dòng)新的活動(dòng)。
          onDestroy():activity被完全從系統(tǒng)內(nèi)存中移除時(shí)調(diào)用,該方法被調(diào)用可能是因?yàn)橛腥酥苯诱{(diào)用 finish()方法 或者系統(tǒng)決定停止該活動(dòng)以釋放資源。

          橫豎屏切換

          1 切換到橫屏
          onSaveInstanceState
          onPause
          onStop
          onDestroy
          onCreate
          onStart
          onRestoreInstanceState
          onResume

          2 切換到豎屏,銷毀了兩次
          onSaveInstanceState
          onPause
          onStop
          onDestroyonCreate
          onStart
          onRestoreInstanceState
          onResume
          onSaveInstanceState
          onPause
          onStop
          onDestroy
          onCreate
          onStart
          onRestoreInstanceState
          onResume

          3 修改AndroidManifest.xml,把該Activity添加 android:configChanges="orientation",切橫屏,只銷毀一次。

          onSaveInstanceState
          onPause
          onStop
          onDestroy
          onCreate
          onStart
          onRestoreInstanceState
          onResume

          再切回豎屏,發(fā)現(xiàn)不會(huì)再打印相同信息,但多打印了一行onConfigChanged

          onSaveInstanceState
          onPause
          onStop
          onDestroy
          onCreate
          onStart
          onRestoreInstanceState
          onResume
          onConfigurationChanged

          5 更改 android:configChanges="orientation" 改成 android:configChanges="orientation|keyboardHidden",切橫屏,就只打印onConfigChanged

          onConfigurationChanged

          6 切回豎屏

          onConfigurationChanged
          onConfigurationChanged

          總結(jié):

          1、不設(shè)置Activity的android:configChanges時(shí),切屏?xí)匦抡{(diào)用各個(gè)生命周期,切橫屏?xí)r會(huì)執(zhí)行一次,切豎屏?xí)r會(huì)執(zhí)行兩次

          2、設(shè)置Activity的android:configChanges="orientation"時(shí),切屏還是會(huì)重新調(diào)用各個(gè)生命周期,切橫、豎屏?xí)r只會(huì)執(zhí)行一次

          3、設(shè)置Activity的android:configChanges="orientation|keyboardHidden"時(shí),切屏不會(huì)重新調(diào)用各個(gè)生命周期,只會(huì)執(zhí)行onConfigurationChanged方法





          posted @ 2011-09-16 10:32 lincode 閱讀(3372) | 評(píng)論 (1)編輯 收藏
          Python 的代碼風(fēng)格由 PEP 8 描述。這個(gè)文檔描述了 Python 編程風(fēng)格的方方面面。在遵守這個(gè)文檔的條件下,不同程序員編寫的 Python 代碼可以保持最大程度的相似風(fēng)格。這樣就易于閱讀,易于在程序員之間交流。


          1 變量

          常量 : 大寫加下劃線
          USER_CONSTANT
          對(duì)于不會(huì)發(fā)生改變的全局變量,使用大寫加下劃線。

          私有變量
          : 小寫和一個(gè)前導(dǎo)下劃線
          _private_value
          Python 中不存在私有變量一說,若是遇到需要保護(hù)的變量,使用小寫和一個(gè)前導(dǎo)下劃線。但這只是程序員之間的一個(gè)約定,用于警告說明這是一個(gè)私有變量,外部類不要去訪問它。但實(shí)際上,外部類還是可以訪問到這個(gè)變量。

          內(nèi)置變量 : 小寫,兩個(gè)前導(dǎo)下劃線和兩個(gè)后置下劃線
          __class__
          兩個(gè)前導(dǎo)下劃線會(huì)導(dǎo)致變量在解釋期間被更名。這是為了避免內(nèi)置變量和其他變量產(chǎn)生沖突。用戶定義的變量要嚴(yán)格避免這種風(fēng)格。以免導(dǎo)致混亂。


          2 函數(shù)和方法

          總體而言應(yīng)該使用,小寫和下劃線。但有些比較老的庫(kù)使用的是混合大小寫,即首單詞小寫,之后每個(gè)單詞第一個(gè)字母大寫,其余小寫。但現(xiàn)在,小寫和下劃線已成為規(guī)范。

          私有方法 : 小寫和一個(gè)前導(dǎo)下劃線
          def _secrete(self):
              
          print "don't test me."

          這里和私有變量一樣,并不是真正的私有訪問權(quán)限。同時(shí)也應(yīng)該注意一般函數(shù)不要使用兩個(gè)前導(dǎo)下劃線(當(dāng)遇到兩個(gè)前導(dǎo)下劃線時(shí),Python 的名稱改編特性將發(fā)揮作用)。特殊函數(shù)后面會(huì)提及。

          特殊方法 : 小寫和兩個(gè)前導(dǎo)下劃線,兩個(gè)后置下劃線

          def __add__(self, other):
              
          return int.__add__(other)

          這種風(fēng)格只應(yīng)用于特殊函數(shù),比如操作符重載等。

          函數(shù)參數(shù) : 小寫和下劃線,缺省值等號(hào)兩邊無空格

          def connect(self, user=None):
              self._user 
          = user



          3 類

          類總是使用駝峰格式命名,即所有單詞首字母大寫其余字母小寫。類名應(yīng)該簡(jiǎn)明,精確,并足以從中理解類所完成的工作。常見的一個(gè)方法是使用表示其類型或者特性的后綴,例如:
          SQLEngine
          MimeTypes

          對(duì)于基類而言,可以使用一個(gè) Base 或者 Abstract 前綴
          BaseCookie
          AbstractGroup

          class UserProfile(object):
              
          def __init__(self, profile):
                  
          return self._profile = profile

              
          def profile(self):
                  
          return self._profile



          4 模塊和包

          除特殊模塊 __init__ 之外,模塊名稱都使用不帶下劃線的小寫字母。
          若是它們實(shí)現(xiàn)一個(gè)協(xié)議,那么通常使用lib為后綴,例如:
          import smtplib

          import os
          import sys



          5 關(guān)于參數(shù)

          5.1 不要用斷言來實(shí)現(xiàn)靜態(tài)類型檢測(cè)
          斷言可以用于檢查參數(shù),但不應(yīng)僅僅是進(jìn)行靜態(tài)類型檢測(cè)。 Python 是動(dòng)態(tài)類型語(yǔ)言,靜態(tài)類型檢測(cè)違背了其設(shè)計(jì)思想。斷言應(yīng)該用于避免函數(shù)不被毫無意義的調(diào)用。

          5.2 不要濫用 *args 和 **kwargs
          *args 和 **kwargs 參數(shù)可能會(huì)破壞函數(shù)的健壯性。它們使簽名變得模糊,而且代碼常常開始在不應(yīng)該的地方構(gòu)建小的參數(shù)解析器。


          6 其他

          6.1 使用 has 或 is 前綴命名布爾元素

          is_connect = True
          has_member 
          = False


          6.2 用復(fù)數(shù)形式命名序列

          members = ['user_1''user_2']


          6.3 用顯式名稱命名字典

          person_address = {'user_1':'10 road WD''user_2' : '20 street huafu'}


          6.4 避免通用名稱
          諸如 list, dict, sequence 或者 element 這樣的名稱應(yīng)該避免。

          6.5 避免現(xiàn)有名稱
          諸如 os, sys 這種系統(tǒng)已經(jīng)存在的名稱應(yīng)該避免。


          7 一些數(shù)字
          一行列數(shù) : PEP 8 規(guī)定為 79 列,這有些苛刻了。根據(jù)自己的情況,比如不要超過滿屏?xí)r編輯器的顯示列數(shù)。這樣就可以在不動(dòng)水平游標(biāo)的情況下,方便的查看代碼。

          一個(gè)函數(shù) : 不要超過 30 行代碼, 即可顯示在一個(gè)屏幕類,可以不使用垂直游標(biāo)即可看到整個(gè)函數(shù)。
          一個(gè)類 : 不要超過 200 行代碼,不要有超過 10 個(gè)方法。
          一個(gè)模塊 不要超過 500 行。


          8 驗(yàn)證腳本

          可以安裝一個(gè) pep8 腳本用于驗(yàn)證你的代碼風(fēng)格是否符合 PEP8。

          >>easy_install pep8

          >>pep8 -r --ignoire E501 Test.py

          這個(gè)命令行的意思是,重復(fù)打出錯(cuò)誤,并且忽略 501 錯(cuò)誤(代碼超過 79 行)。

          posted @ 2011-02-02 00:45 lincode 閱讀(9323) | 評(píng)論 (0)編輯 收藏
          Emacs 不僅僅是一個(gè)文本編輯器,它還可用于文件管理。使用 Emacs 作為文件管理工具的話,也解決了跨平臺(tái)問題,這樣在不同平臺(tái)下,你都可以使用一套工具來管理文件。

          1 基本命令
          Ctrl + x  d  : 打開文件管理視圖,在文件管理視圖中支持的操作如下表:
          鍵值 效果    
          Enter 打開文件
          a 打開文件并關(guān)閉文件管理視圖
          打開文件,但是在一個(gè)新建視圖中打開
          關(guān)閉文件管理視圖
          C(大寫) 復(fù)制文件
          R(大寫) 重命名文件
          D(大寫) 刪除文件


          2 基于文件集合的命令
          這主要是使一條命令作用于幾個(gè)文件。方法是標(biāo)記你要操作的文件。
          基本命令為 m

          鍵值  效果    
          m 標(biāo)記文件
          u 去掉標(biāo)記
          U 標(biāo)記所有文件
          t 反向所以文件
          % m 基于正則表達(dá)式,標(biāo)記文件


          3 其他相關(guān)命令
          在文件管理視圖中還可以做到:
          鍵值 效果    
          g 刷新文件夾
          ^ 返回上級(jí)目錄
          + 創(chuàng)建一個(gè)文件夾
          壓縮或解壓文件


          posted @ 2011-02-01 18:14 lincode 閱讀(1070) | 評(píng)論 (0)編輯 收藏

          我使用的是 goddady 的 VPS。家里使用 mac 。所以直接在 terminal 中使用 ssh 連接服務(wù)器即可。

          > ssh 189.129.1.12 -l username
          敲入密碼,進(jìn)入服務(wù)器。

          > su
          敲入密碼,進(jìn)入根用戶。

          > cd /etc/ngnix/
          進(jìn)入 ngnix 配置文件目錄,進(jìn)入 conf.d 目錄

          > vim ghs.conf
          建立一個(gè) 配置文件

          一個(gè)范例:

          upstream ghs {
              ip_hash;
              server ghs.google.com;
              server 72.14.203.121;
              server 72.14.207.121;
              server 74.125.43.121;
              server 74.125.47.121;
              server 74.125.53.121;
              server 74.125.77.121;
              server 74.125.93.121;
              server 74.125.95.121;
              server 74.125.113.121;
              server 216.239.32.21;
              server 216.239.34.21;
              server 216.239.36.21;
              server 216.239.38.21;
          }

          server {
              listen       80;
              server_name  ghs.myhosts.com www.test.com;
              access_log   /data/logs/ghs_proxyaccess.log;

              location / {
                  proxy_redirect off;
                  proxy_set_header Host $host;
                  proxy_pass http://ghs;
                  proxy_set_header  X-Real-IP  $remote_addr;
                  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                  proxy_redirect false;
              }

          }


          >/etc/init.d/ngnix start

          啟動(dòng) nginx

          在本機(jī)的瀏覽器中敲入反向代理 server 的 ip,能看到 ngnix 的藍(lán)色的界面,這驗(yàn)證了 ngnix 啟動(dòng)正常

          > ping ghs.myhosts.com
          應(yīng)該指向反向代理 server 的 ip

          首先將你的域名例如,www.tests.com  綁定到 google app engine 的你的目標(biāo) application 上
          然后,在你的域名服務(wù)提供商那里,添加一個(gè) www.tests.com 指向 ghs.myhosts.com 的 CNAME 即可。

          posted @ 2010-12-15 07:12 lincode 閱讀(503) | 評(píng)論 (0)編輯 收藏

            transient:

            java有個(gè)特點(diǎn)就是序列化,簡(jiǎn)單地來說就是可以將這個(gè)類存儲(chǔ)在物理空間(當(dāng)然還是以文件的形式存在),那么當(dāng)你從本地還原這個(gè)文件時(shí),你可以將它轉(zhuǎn)換為它本身。這可以極大地方便網(wǎng)絡(luò)上的一些操作,但同時(shí),因?yàn)樯婕暗桨踩珕栴},所以并不希望把類里面所有的東西都能存儲(chǔ)(因?yàn)槟菢樱瑒e人可以通過序列化知道類里面的內(nèi)容),那么我們就可以用上transient這個(gè)關(guān)鍵字,它的意思是臨時(shí)的,即不會(huì)隨類一起序列化到本地,所以當(dāng)還原后,這個(gè)關(guān)鍵字定義的變量也就不再存在。

            volatile:

            Volatile 修飾的成員變量在每次被線程訪問時(shí),都強(qiáng)迫從共享內(nèi)存中重讀該成員變量的值。而且,當(dāng)成員變量發(fā)生變化時(shí),強(qiáng)迫線程將變化值回寫到共享內(nèi)存。這樣在任何時(shí)刻,兩個(gè)不同的線程總是看到某個(gè)成員變量的同一個(gè)值。

            Java 語(yǔ)言規(guī)范中指出:為了獲得最佳速度,允許線程保存共享成員變量的私有拷貝,而且只當(dāng)線程進(jìn)入或者離開同步代碼塊時(shí)才與共享成員變量的原始值對(duì)比。

            這樣當(dāng)多個(gè)線程同時(shí)與某個(gè)對(duì)象交互時(shí),就必須要注意到要讓線程及時(shí)的得到共享成員變量的變化。

            而volatile關(guān)鍵字就是提示VM:對(duì)于這個(gè)成員變量不能保存它的私有拷貝,而應(yīng)直接與共享成員變量交互。

            使用建議:在兩個(gè)或者更多的線程訪問的成員變量上使用volatile。當(dāng)要訪問的變量已在synchronized代碼塊中,或者為常量時(shí),不必使用。

            由于使用volatile屏蔽掉了VM中必要的代碼優(yōu)化,所以在效率上比較低,因此一定在必要時(shí)才使用此關(guān)鍵字。

          posted @ 2010-06-14 23:03 lincode 閱讀(228) | 評(píng)論 (0)編輯 收藏

          一 基本概念
          單例模式是一種為類 提供唯一實(shí)例的設(shè)計(jì)模式。單例模式的目的是為了控制對(duì)象的創(chuàng)建,它可以限制創(chuàng)建的數(shù)目為一,但在情況改變的時(shí)候,也允許靈活地創(chuàng)建更多的對(duì)象。因?yàn)橹挥幸粋€(gè)實(shí)例,所以也只有一套實(shí)例的類變量的拷貝,這很像 static 變量。

          在 JAVA 中,單例模式不應(yīng)該被當(dāng)作一種實(shí)現(xiàn)全局變量的方法。更多的,如同工廠模式,單例模式允許你通過 確認(rèn)某些先決條件是否滿足 或者 以 lazily 方式按需創(chuàng)建的方式 來封裝和控制創(chuàng)建過程。

          二 編程實(shí)現(xiàn)
          1 饑餓模式 Eager Singleton

          public class MySingleton {
              
          private static MySingleton fInstance = new MySingleton();
              
              
          private MySingleton(){
                  
          // Construct object 
              }


              
          public static MySingleton getInstance(){
                  reutnr fInstance;
              }


          }

          2 懶漢模式 Lazy Singleton

          public class MySingleton {
              
          private static MySingleton fInstance;
              
              
          private MySingleton(){
                  
          // construct object
              }

              
              
          public static synchronized MySingleton getInstance(){
                  
          if (fInstance == null){
                      fInstance 
          = new MySingleton();
                  }

                  
          return fInstance;
              }


          }

          由于只有一個(gè)私有構(gòu)造器,所以單例類是無法被集成的?;谶@一點(diǎn),單例模式并不是一個(gè)面向?qū)ο竽J?,僅僅是一個(gè)基于對(duì)象的模式。

          3 饑餓模式基本沒有問題,懶漢模式則容易出現(xiàn)一些錯(cuò)誤的編程方法
          1)
          // error, no synchronization on method 
          public static MySingleton getInstance() 
           
          if (fInstance==null
               fInstance 
          = new MySingleton(); 
           }
           

           
          return fInstance; 
          }

          2)
          // Also an error, synchronization does not prevent 
          // two calls of constructor. 
          public static MySingleton getInstance() 
           
          if (fInstance==null
             
          synchronized (MySingleton.class
                fInstance 
          = new MySingleton(); 
             }
           
           }
           
           
          return fInstance; 
          }
           

          3) Double-checked locking 不要使用

          public static MySingleton getInstance(){
              
          if (fInstance == null ){
                  
          synchronized (MySingleton.class{
                      
          if(fInstance == null){
                          fInstance 
          = new MySingleton();
                      }

                  }

              }

          }

          為了避免每次調(diào)用 getInstance方法是抓取同步鎖的消耗,有人發(fā)明了 Double-checked locking 。但不要使用,因?yàn)檫@樣的代碼將無法在編譯器優(yōu)化和多處理器共享內(nèi)存的情況下工作。若想詳細(xì)了解,附錄中有對(duì)此做詳細(xì)描述的鏈接。

          三 總結(jié)

          1 單例模式不應(yīng)被濫用,比如不能為了得到一個(gè)全局變量而創(chuàng)建單例,單例是用于控制對(duì)象的創(chuàng)建過程的。只有真正的目的是控制對(duì)象創(chuàng)建的過程或數(shù)量時(shí),才能考慮使用單例。在大部分情況下,單例模式是有代替方案的。比如經(jīng)典的數(shù)據(jù)庫(kù)連接類被以單例實(shí)現(xiàn),其實(shí)可以以對(duì)象池模式實(shí)現(xiàn)。

          2 使用單例模式,盡量使用饑餓模式 ,只有你能預(yù)測(cè)這個(gè)類一定會(huì)被創(chuàng)建,那么就可以使用饑餓模式。如果,一定需要推遲對(duì)象的創(chuàng)建時(shí)間。那么不要使用 Double-checked locking 之類的方法的來提高效率,這將得不償失。

          [1] DoubleCheckedLocking
          http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
          posted @ 2010-04-30 21:04 lincode 閱讀(217) | 評(píng)論 (0)編輯 收藏

          一 基本概念
          這篇文章比較清楚地講述了字符集和編碼的基本概念
          http://www.regexlab.com/zh/encoding.htm

          摘抄:

          各個(gè)國(guó)家和地區(qū)所制定的不同 ANSI 編碼標(biāo)準(zhǔn)中,都只規(guī)定了各自語(yǔ)言所需的“字符”。比如:漢字標(biāo)準(zhǔn)(GB2312)中沒有規(guī)定韓國(guó)語(yǔ)字符怎樣存儲(chǔ)。這些 ANSI 編碼標(biāo)準(zhǔn)所規(guī)定的內(nèi)容包含兩層含義:

          1. 使用哪些字符。也就是說哪些漢字,字母和符號(hào)會(huì)被收入標(biāo)準(zhǔn)中。所包含“字符”的集合就叫做“字符集”。
          2. 規(guī)定每個(gè)“字符”分別用一個(gè)字節(jié)還是多個(gè)字節(jié)存儲(chǔ),用哪些字節(jié)來存儲(chǔ),這個(gè)規(guī)定就叫做“編碼”。

          各個(gè)國(guó)家和地區(qū)在制定編碼標(biāo)準(zhǔn)的時(shí)候,“字符的集合”和“編碼”一般都是同時(shí)制定的。因此,平常我們所說的“字符集”,比如:GB2312, GBK, JIS 等,除了有“字符的集合”這層含義外,同時(shí)也包含了“編碼”的含義。

          UNICODE 字符集”包含了各種語(yǔ)言中使用到的所有“字符”。用來給 UNICODE 字符集編碼的標(biāo)準(zhǔn)有很多種,比如:UTF-8, UTF-7, UTF-16, UnicodeLittle, UnicodeBig 等。


          二 eclipse 中對(duì)于編碼方式的設(shè)置

          1 源文件的編碼設(shè)置

          preference -> general -> Content Types 
          右邊選擇文件類型,右下更新 缺省編碼方式

          2 控制臺(tái)的編碼設(shè)置
          Run -> Run configuration( 或 Debug configuration)
          右邊選項(xiàng)卡中 common, 一般為最后一項(xiàng)
          在 console encoding 的 other 中選取需要的 編碼方式

          三 java 中的 編碼轉(zhuǎn)換

          byte[] bytes = oldStr.getBytes(); //默認(rèn)編碼方式下的字節(jié)數(shù)組
          String newStr = new String( bytes, "UTF-8" ); //轉(zhuǎn)換成 UTF-8 編碼下的字符串


           
          posted @ 2010-04-29 23:31 lincode 閱讀(262) | 評(píng)論 (0)編輯 收藏

          Java 中函數(shù)參數(shù)傳遞和函數(shù)返回值都是以值方式傳遞的。當(dāng)然,對(duì)于對(duì)象,我們也可以說是引用的方式傳遞,其實(shí)傳遞也是值,只不過是引用值。引用是一個(gè)對(duì)象的別名,對(duì)于引用的修改就是對(duì)于對(duì)象本身的修改。

          為了便于理解還是可以說成是兩種類型,原始類型以值方式傳遞,對(duì)象以引用方式傳遞。

          向函數(shù)里傳遞參數(shù),已經(jīng)有很多java教程講解了。這里主要記錄一個(gè) 函數(shù)返回值的問題。在返回一個(gè)對(duì)象時(shí),是返回值本身的應(yīng)用,還是拷貝這個(gè)值,再傳拷貝的引用呢。這是需要考慮清楚的。

          這個(gè)問題,是我在 不同手機(jī)上調(diào)試 J2ME 程序時(shí)遇到的。

          具體如下,這是一個(gè)關(guān)于時(shí)間的工具類。我發(fā)覺 Calendar 的 getTime() 在有的機(jī)器下 如 Nokia,返回的 Calendar 當(dāng)前時(shí)間的一個(gè)拷貝的引用,而 SAMSUNG 則直接返回 Calendar 的當(dāng)前時(shí)間的引用。這導(dǎo)致,我在想得到一個(gè)時(shí)間所在那一的起始時(shí)間和結(jié)束時(shí)間時(shí),總是得到相同的值,即后一次調(diào)用的值。按照,比較正常的理解,這里應(yīng)該返回拷貝的引用比較正確,就是說 SAMSUNG 的 JVM 實(shí)現(xiàn)有些問題。面對(duì)這種情況,我只能先用 Date 類 返回 一個(gè) long 值,再用 long 值構(gòu)造一個(gè)新日期,即日歷當(dāng)前日期的拷貝,返回這個(gè)拷貝。

          修改函數(shù)中的最后一行為
          return new Date(fCalendar.getTime().getTime());

              private static Date fCalendar = Calendar.getInstance();


              
          /**
                       * Get the beginning of a day
                       * 
          @param date <description>
                       * 
          @return <description>
                       
          */
              
          public static Date getBeginOfDay( final Date pDate ) {
                  
                 fCalendar.setTime( pDate );
                 
          try{
                     fCalendar.set( Calendar.HOUR_OF_DAY, 
          0 );
                     fCalendar.set( Calendar.MINUTE, 
          0 );
                     fCalendar.set( Calendar.SECOND, 
          0 );
                  }
          catch(ArrayIndexOutOfBoundsException ex){
                      ex.printStackTrace();
                  } 
                  
          return fCalendar.getTime();
              }
             
              
          /**
                       * Get the end of a day
                       * 
          @param date <description>
                       * 
          @return <description>
                       
          */
              
          public static Date getEndOfDay( final Date pDate ){
                  
                 fCalendar.setTime( pDate );
                 
          try{
                     fCalendar.set( Calendar.HOUR_OF_DAY, 
          23 );
                     fCalendar.set( Calendar.MINUTE, 
          59 );
                     fCalendar.set( Calendar.SECOND, 
          59 );
                  }
          catch(ArrayIndexOutOfBoundsException ex){
                      ex.printStackTrace();
                  }
                  
          return fCalendar.getTime();
              }





          posted @ 2010-02-24 21:36 lincode 閱讀(2327) | 評(píng)論 (0)編輯 收藏
               摘要: 原則很簡(jiǎn)單: 不要使用 字符串鏈接操作符來合并多個(gè)字符串,除非性能無關(guān)緊要。相反,應(yīng)該使用StringBuffer的append方法,或者采用其它的方案,比如使用字符數(shù)組,或者每次只處理一個(gè)字符串,而不是將它們組合起來。  閱讀全文
          posted @ 2010-02-10 18:46 lincode 閱讀(425) | 評(píng)論 (0)編輯 收藏
          主站蜘蛛池模板: 嵊州市| 宁波市| 稻城县| 治县。| 屯门区| 集贤县| 大丰市| 鄂托克旗| 固阳县| 安国市| 静安区| 烟台市| 浮梁县| 青田县| 石台县| 武川县| 咸阳市| 河南省| 南康市| 中西区| 建始县| 开原市| 美姑县| 西平县| 承德县| 宜丰县| 织金县| 绥棱县| 嘉祥县| 泸水县| 海兴县| 巴彦县| 龙泉市| 林州市| 恩平市| 葵青区| 靖西县| 霞浦县| 闻喜县| 平安县| 花莲县|