ã¢ããªã±ãŒã·ã§ã³ã®ãããã¯ãŒã¯éšåãå®è£ ããéã«èŠããŠããã¹ãããš
æåã¯äº€éã§ãã ç¡æã®Wi-Fiæ¥ç¶ã§äœæ¥ã§ãããšã¯éããŸããããŸããã¢ãã€ã«ã€ã³ã¿ãŒãããã¯äŸç¶ãšããŠé«äŸ¡ã§ãããã©ãã£ãã¯ã¯ãŠãŒã¶ãŒã®ãéã§ãããããããã¯èŠããŠããå¿ èŠããããŸãã
2çªç®ã¯ããããªãŒã®å¶éã§ãã ã¢ãã€ã«ããã€ã¹ã¯ãäžéšã®æ¥åžžçãªæŽ»åãäŒè°ãæ£æ©ãããžãã¹ã®ããã«ãŠãŒã¶ãŒã«å¿ èŠã§ãããããããªãŒãæãäžé©åãªç¬éã«ãªããªããšããŠãŒã¶ãŒã¯inããŸãã
3çªç®ã¯ã»ãã¥ãªãã£ã§ãã ç§ãã¡ãã¢ãã€ã«ã¯ã©ã€ã¢ã³ãã«ã€ããŠè©±ããŠããã®ãšåãã§ãããŒã¿ãã¯ã©ã€ã¢ã³ããããµãŒããŒãžããŸãã¯ãã®éã«ãããã¯ãŒã¯äžã移åããŠããã®ã§ãããããä¿è·ããå¿ èŠããããŸãã
ãããã¯ãŒãã³ã°ã¢ãããŒã
ãŸããã¯ã©ã€ã¢ã³ã/ãµãŒããŒéä¿¡ãå®è£ ããæ¹æ³ãååšããä»æ¥äžè¬çã«äœ¿çšãããŠããããšãæãåºããŠãã ããã
æåã®ã¢ãããŒãã¯ãœã±ããã«åºã¥ããŠããŸãïŒããã§ã¯Socket APIãçŽæ¥æäœããããšãæå³ããŸãïŒã å€ãã®å Žåãã¡ãã»ãŒãžé ä¿¡ã®é床ãéèŠã§ãããã¡ãã»ãŒãžé ä¿¡ã®é åºãéèŠã§ããããµãŒããŒãžã®å®å®ããæ¥ç¶ãç¶æããå¿ èŠãããã¢ããªã±ãŒã·ã§ã³ã§äœ¿çšãããŸãã ãã®ã¡ãœããã¯ãå€ãã®å Žåãã€ã³ã¹ã¿ã³ãã¡ãã»ã³ãžã£ãŒããã³ã²ãŒã ã§å®è£ ãããŸãã
2çªç®ã®ã¢ãããŒãã¯é »ç¹ãªããŒãªã³ã°ã§ããã¯ã©ã€ã¢ã³ãã¯ãªã¯ãšã¹ãããµãŒããŒã«éä¿¡ããããã次ã®ããã«äŒããŸãã ãµãŒããŒã¯ã¯ã©ã€ã¢ã³ãã®ãªã¯ãšã¹ãã«å¿çãããã®æç¹ãŸã§ã«èç©ãããã¹ãŠãæäŸããŸãã
ãã®ã¢ãããŒãã®æ¬ ç¹ã¯ãã¯ã©ã€ã¢ã³ãããµãŒããŒã«æ°ããããŒã¿ãçŸãããã©ãããç¥ããªãããšã§ãã äž»ã«ãµãŒããŒãžã®é »ç¹ãªæ¥ç¶ãåå ã§ããããã¯ãŒã¯äžã§ãã©ãã£ãã¯ãåã³è¿œè·¡ãããŠããŸãã
3çªç®ã®ã¢ãããŒã-é·ãããŒãªã³ã°-ã¯ãã¯ã©ã€ã¢ã³ãããµãŒããŒã«ãä¿çãèŠæ±ãéä¿¡ããããšã§ãã ãµãŒããŒã¯ãã¯ã©ã€ã¢ã³ãã®ææ°ããŒã¿ããããã©ããã確èªãããªãå Žåã¯ããã®ããŒã¿ã衚瀺ããããŸã§ã¯ã©ã€ã¢ã³ããšã®æ¥ç¶ãç¶æããŸãã ããŒã¿ã衚瀺ããããšããã«ã圌ã¯ããããã¯ã©ã€ã¢ã³ãã«ãããã·ã¥ãããŸãã ãµãŒããŒããããŒã¿ãåä¿¡ããã¯ã©ã€ã¢ã³ãã¯ãããã«æ¬¡ã®ãä¿çäžãèŠæ±ãªã©ãéä¿¡ããŸãã
ãã®ã¢ãããŒãã®å®è£ ã¯ãäž»ã«ã¢ãã€ã«æ¥ç¶ã®äžå®å®æ§ã®ãããã¢ãã€ã«ã¯ã©ã€ã¢ã³ãã§ã¯ããªãè€éã§ãã ãããããã®ã¢ãããŒãã§ã¯ãéåžžã®ããŒãªã³ã°ãããå°ãªããã©ãã£ãã¯ãæ¶è²»ãããŸãã ãµãŒããŒæ¥ç¶èšå®ã®æ°ãåæžãããŸãã
é·ãããŒãªã³ã°ã®ã¡ã«ããºã ããŸãã¯ããã·ã¥éç¥ã¯ãAndroidãã©ãããã©ãŒã èªäœã«å®è£ ãããŠããŸãã ãããŠããããããã»ãšãã©ã®ã¿ã¹ã¯ã§ã¯ãèªåã§å®è£ ããã®ã§ã¯ãªãã䜿çšããæ¹ãè¯ãã§ãããã ã¢ããªã±ãŒã·ã§ã³ã¯ãããã·ã¥éç¥ãåä¿¡ããããã«Google Cloud MessagingïŒGCMïŒãµãŒãã¹ã«ãµãã¹ã¯ã©ã€ãããŸãã
ããã¯ããµãŒããŒãGCMãµãŒãã¹ãšé£æºããåžžã«ãã®ãµãŒãã¹ã«æ°ããããŒã¿ãéä¿¡ããããããµãŒããŒãšã¯ã©ã€ã¢ã³ãéã®æ¥ç¶ãçŽæ¥åæãããã®ããŒã¿ãã¢ããªã±ãŒã·ã§ã³ã«é ä¿¡ããããã®ãã¹ãŠã®ããžãã¯ãå®è£ ããŸãã ãã®ã¢ãããŒãã®å©ç¹ã¯ãããŒã¿ã確å®ã«åºçŸããããšã確å®ã«ç¥ã£ãŠããããããµãŒããŒã«é »ç¹ã«æ¥ç¶ããå¿ èŠããªããªããGCMãµãŒãã¹ãããã«ã€ããŠéç¥ããããšã§ãã
ããã4ã€ã®ã¢ãããŒãã®ãã¡ãããã·ã¥éç¥ãšé »ç¹ãªããŒãªã³ã°ã¯ãããžãã¹ã¢ããªã±ãŒã·ã§ã³ãéçºããéã«æãäžè¬çã§ãã ãããã®ã¢ãããŒããå®è£ ããå Žåãäœããã®æ¹æ³ã§ãµãŒããŒãžã®æ¥ç¶ã確ç«ããããŒã¿ã転éããå¿ èŠããããŸãã 次ã«ãéçºè ãHTTP / HTTPSãããã³ã«ãæäœããããã«äœ¿çšã§ããããŒã«ã«çŠç¹ãåœãŠãŸãã
HttpUrlConnectionããã³HttpClient
Androidéçºè ã®æŠåšã«ã¯ããããã®ãããã³ã«ãæäœããããã®2ã€ã®ã¯ã©ã¹ããããŸãã æåã¯java.net.HttpURLConnectionã2çªç®ã¯org.apache.http.client.HttpClientã§ãã ãããã®ã©ã€ãã©ãªã¯äž¡æ¹ãšãAndroid SDKã«å«ãŸããŠããŸãã 次ã«ããããã®åã©ã€ãã©ãªãæäœãããšãã«ãã©ãã£ãã¯ãããããªãŒãã»ãã¥ãªãã£ã«åœ±é¿ããäž»ãªãã€ã³ãã«ã€ããŠè©³ãã説æããŸãã
HttpURLConnectionã䜿çšãããšããã¹ãŠãç°¡åã«ãªããŸãã 1ã€ã®ã¯ã©ã¹ãšãã¹ãŠã ããã¯ã芪ã¯ã©ã¹URLConnectionãHTTPãããã³ã«ã ãã§ãªãããã¡ã€ã«ãmailtoãftpãªã©ã§ãæ©èœããããã«èšèšãããŠããããã§ãã
HttpClientã¯ããããªããžã§ã¯ãæåã«ãªãããã«èšèšãããŠããŸãã æœè±¡åãæ確ã«åé¢ãããŠããŸãã æãåçŽãªã±ãŒã¹ã§ã¯ã5ã€ã®ç°ãªãã€ã³ã¿ãŒãã§ã€ã¹ãHttpRequestãHttpResponseãHttpEntityãããã³HttpContextã䜿çšããŸãã ãããã£ãŠãApachevã¯ã©ã€ã¢ã³ãã¯HttpUrlConnectionãããããªãéãã§ãã
éåžžãã¢ããªã±ãŒã·ã§ã³ããšã«HttpClientã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã¯1ã€ã ãã§ãã ããã¯ããã®éãã«ãããã®ã§ãã ãªã¯ãšã¹ãããšã«åå¥ã®ã€ã³ã¹ã¿ã³ã¹ã䜿çšããã®ã¯ç¡é§ã§ãã ããšãã°ãHTTPã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãApplicationã¯ã©ã¹ã®åŸç¶ã«æ ŒçŽã§ããŸãã
HttpUrlConnectionã®å Žåããªã¯ãšã¹ãããšã«æ°ããã¯ã©ã€ã¢ã³ãã€ã³ã¹ã¿ã³ã¹ãäœæããå¿ èŠããããŸãã
ãã©ãã£ãã¯ã¯äœã§æ§æãããŠããŸããïŒ
ã¢ããªã±ãŒã·ã§ã³ã®å®è¡äžãç»åã¯æ¬¡ã®ããã«ãªããŸãã
èŠæ±ã®æ°ãšé »åºŠã¯ãUI-ã¢ããªã±ãŒã·ã§ã³ã€ã³ã¿ãŒãã§ã€ã¹ã®æ©èœãšé£œå床ã«äŸåããŸãã ãã®ãããªåèŠæ±ã¯ããµãŒããŒãžã®TCPæ¥ç¶ã確ç«ããŸãã ãã®å Žåãæ¶è²»ããããã©ãã£ãã¯ã¯ãæ¥ç¶èšå®ã®åèšãšéä¿¡ããŒã¿ã®åèšã«çãããªããŸãã ãã®å Žåãé·çãããæ¥ç¶ïŒããŒãã¢ã©ã€ãïŒã䜿çšããããšã«ããããã©ãã£ãã¯æ¶è²»ãåæžã§ããŸãã
ããŒãã¢ã©ã€ãã®åºæ¬çãªèãæ¹ã¯ãåãTCPæ¥ç¶ã䜿çšããŠHTTPèŠæ±ãéåä¿¡ããããšã§ãã äž»ãªå©ç¹ã¯ããã©ãã£ãã¯ã®åæžãšã¯ãšãªã®å®è¡æéã§ãã ç°¡åãªãã¹ããè¡ããŸãããããã¯ãåããã¹ãã«å¯ŸããŠ10åã®ãªã¯ãšã¹ããé çªã«å®è¡ããããšããäºå®ããæããŸããã 以äžã®è¡šã«ããŒã¿ã瀺ããŸãã ããŒãã¢ã©ã€ãããªãã«ãããšãå¹³åã¯ãšãªå®è¡æéãçŽ2ç§ã§ããããšãããããŸãã ããŒãã¢ã©ã€ããæå¹ã«ããå Žåããã®æéã¯1.7ç§ã«ççž®ããã16ïŒ éããªããŸããã ããã¯äž»ã«ããµãŒããŒãžã®æ¥ç¶ãé »ç¹ã«ç¢ºç«ããå¿ èŠããªããªãããã§ãã å®å šãªHTTPSæ¥ç¶ã䜿çšããå Žåãéãã¯ããé¡èã«ãªããŸãã SSLãã³ãã·ã§ã€ã¯ã¯ãTCPãã³ãã·ã§ã€ã¯ãããã¯ããã«å°é£ã§ãã
ããŒãã¢ã©ã€ãæ¥ç¶ã®éèŠãªãã©ã¡ãŒã¿ãŒã¯ãããŒãã¢ã©ã€ãæéã§ãã æéééãæå³ããŸãã ãã®ééå ã«è€æ°ã®HTTPèŠæ±ãå°çãããšããã§ã«ç¢ºç«ãããŠããTCPæ¥ç¶ãåå©çšãããŸãã
å³ããã4çªç®ãš3çªç®ã®èŠæ±ã®éã®æéãããŒãã¢ã©ã€ãæéãè¶ ããŠããããããµãŒããŒãžã®æ°ããTCPæ¥ç¶ãäœæãããŠããããšãããããŸãã
äžèšã®ãã©ã¡ãŒã¿ãŒãèšå®ããæ¹æ³ãèŠãŠã¿ãŸãããã HttpClientã®å Žåããã¹ãŠåé¡ãããŸãããConnectionKeepAliveStrategyã€ã³ã¿ãŒãã§ã€ã¹ãèªç±ã«äœ¿çšã§ããŸãã getKeepAliveDurationã¡ãœããããªãŒããŒã©ã€ãããããšã«ãããããŒãã¢ã©ã€ãæéãã©ã¡ãŒã¿ãŒã®ç®çã®å€ãè¿ãããšãã§ããŸãã
httpClient.setKeepAliveStrategy( new ConnectionKeepAliveStrategy() { @Override public long getKeepAliveDuration( HttpResponse response, HttpContext context) { return KEEP_ALIVE_DURATION_MILLISECONDS; } });
HttpUrlConnectionã䜿çšããå Žåã¯ãAndroid 2.2ãã©ãããã©ãŒã ã®ãã°ãæãåºãã 2.2以äžã®ãã©ãããã©ãŒã ã§ããŒãã¢ã©ã€ããç¡å¹ã«ããå¿ èŠããããŸãã
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { System.setProperty("http.keepAlive", "false"); }
HttpUrlConnectionãæäœãããšãã®2çªç®ã®äžå¿«ãªïŒããããç§ã ãã®ïŒç¬éã¯ãããŒãã¢ã©ã€ãæéãã©ã¡ãŒã¿ãŒãæ§æã§ããªãããšã§ãïŒèª°ããç§ã«æè¬ãããšèšãå Žåãåæ³çãªæ¹æ³ã¯èŠã€ãããŸããã§ããïŒã ããã©ã«ãã§ã¯ãçŽ5ç§ã§ãã
ãŸããããŒãã¢ã©ã€ãæ¥ç¶ã§äœæ¥ããå Žåã確ç«ãããæ¥ç¶ïŒæ¥ç¶ïŒããããŒã¿ãå®å šã«èªã¿åãããšããå¿ èŠããããŸãã ããŒã¿ãèªã¿åããªããšãããŒã«ã§ãã³ã°ã¢ããããæ¥ç¶ãååŸã§ããä»ã®èª°ããããããèªã¿åãããšããŠãããšãèãããããšãã§ããŸãã InputStreamãæ£åžžã«åä¿¡ãããå Žåãå¿çæ¬æå šäœãèªã¿åããŸãã å®å šãªèªã¿åã㯠ãããŒã¿ããæ¥ç¶ãã¯ãªã¢ãããã®æ¥ç¶ã¯åå©çšãããå¯èœæ§ãé«ããªããŸãã
ã¯ãããŒ
Cookieã¯ãWebãµãŒããŒããéä¿¡ããããŠãŒã¶ãŒã®ã³ã³ãã¥ãŒã¿ãŒã«ä¿åãããå°ããªããŒã¿ã§ãã ãã®å Žåãã³ã³ãã¥ãŒã¿ãŒã¯Androidããã€ã¹ã§ãã å®éã«ã¯ãCookieã¯éåžžããŠãŒã¶ãŒã®èªèšŒããŠãŒã¶ãŒã®å人èšå®ãšèšå®ã®ä¿åããŠãŒã¶ãŒã®ã¢ã¯ã»ã¹ã»ãã·ã§ã³ã®ã¹ããŒã¿ã¹ã®è¿œè·¡ãããã³ãŠãŒã¶ãŒã«é¢ããçµ±èšã®ä¿æã«äœ¿çšãããŸãã ãµã€ãã®ã¢ãã€ã«ããŒãžã§ã³ãæ¢ã«äœæãããåŸãå€æ°ã®ãµãŒãã¹ãã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³ã®éçºãéå§ããŸãã ãã®ãããªç¶æ³ã§ã¯ããã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³ã§èªèšŒCookieãåãåã£ãŠããã©ãŠã¶ãŒïŒWebViewã§ïŒã«ã€ã³ã¹ããŒã«ããããšã¯å¯èœã§ããïŒããšãã質åãèå³æ·±ãã§ãã ãã®åé¡ã解決ãããšããæéãç¯çŽããã®ã«åœ¹ç«ã€ããã€ãã®è©³çŽ°ããããŸãã
- ãã©ãããã©ãŒã > = 4.0.3ïŒAPIã¬ãã«15ïŒ ã§ã¯ããã¡ã€ã³ã®å é ã«ããããå¿ èŠã§ã
- CookieSyncManagerã®syncïŒïŒã¡ãœãããåŒã³åºããåŸãCookieã¯ã¢ããªã±ãŒã·ã§ã³å ã®WebViewã§ã®ã¿èšå®ããããã©ãŠã¶ãŒã§ã¯èšå®ãããŸãã ã ãã®å¶éã¯ãã»ãã¥ãªãã£äžã®çç±ããAndroidã·ã¹ãã ã«ãã£ãŠèª²ãããŠããŸãã
ã»ãã¥ã¢æ¥ç¶ïŒHTTPSïŒ
ãã®èšäºã®æåŸã§ãAndroidã§HTTPSãæå¹ã«ããæ¹æ³ã«ã€ããŠèª¬æããŸãã ç§ã®ç¥ãéããä»ã®ã¢ãã€ã«ãã©ãããã©ãŒã ã§ã¯ãHTTPSã¹ããŒã ãSSLãã©ã³ã¹ããŒãã¡ã«ããºã ãæå¹ã«ããã ãã§ååã§ãã Androidã«ã¯ãèæ ®ããŠå¯ŸåŠãã¹ãåé¡ãããã€ããããŸãã ãŸããå®å šãªæ¥ç¶ãã©ã®ããã«ç¢ºç«ãããããèŠããŠãããŠãã ããã èµ€ãç¢å°ã¯åé¡ç¹ãæããŸã-ããã¯èšŒææžèªèšŒã§ãã
ãã©ãããã©ãŒã <Android 4.0ã§ãHTTPSãä»ããŠãããã¯ãŒã¯èŠæ±ãå®è¡ããããšãããšãSSLHandshakeExceptionãã¯ã©ãã·ã¥ããŸãã ä¿¡é Œã§ãã蚌ææžãã€ã³ã¹ããŒã«ããæ©èœã¯ã KeyChain APIã䜿çšããŠAndroid 4.0ã«ç»å ŽããŸããã ãããã4.0以äžã®ãã©ãããã©ãŒã ã«ã€ããŠã¯ã©ãã§ããããïŒ ãããã®ãã©ãããã©ãŒã ã§ã¯ã2ã€ã®ãªãã·ã§ã³ããããŸãã
- ããŒã«ã«èšŒææžã¹ãã¢ãäœæãã
- 蚌ææžãä¿¡é ŒããŸãã ãã®å Žåããã©ãã£ãã¯ãæå·åãããŸãããäžéæ»æè ã®è åšã¯æ®ããŸã
ããŒã«ã«èšŒææžã¹ãã¢ã®äœæãéžæãããå ŽåãäœæåŸã次ã®ããã«æ¥ç¶ã§ããŸãã
-HttpUrlConnectionã®å ŽåïŒ
...
TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); KeyStore keyStore = KeyStore.getInstance("BKS"); InputStream in = context.getResources().openRawResource(mykeystore); keyStore.load(in, "mysecret".toCharArray()); in.close(); tmf.init(keyStore); SSLContext sslc = SSLContext.getInstance("TLS"); sslc.init(null, tmf.getTrustManagers(),new SecureRandom());
...
-HttpClientã®å ŽåïŒ
private SSLSocketFactory createSslSocketFactory() { SSLSocketFactory sf = null; try { KeyStore keyStore = KeyStore.getInstance("BKS"); InputStream in = context.getResources().openRawResource(mykeystore); keyStore.load(in, "mysecret".toCharArray()); in.close(); sf = new SSLSocketFactory(keyStore); sf.setHostnameVerifier(STRICT_HOSTNAME_VERIFIER); } catch (Exception e) { e.printStackTrace(); } return sf; }.
KeyStore.getInstanceïŒãBKSãïŒã䜿çšããŠãBounce Castle KeyStore圢åŒïŒæå·ã¢ã«ãŽãªãºã ãæäœããããã®Javaããã±ãŒãžïŒããµããŒãããKeyStoreãªããžã§ã¯ããååŸããŸãã mykeystore-蚌ææžãé 眮ãããŠãããªãœãŒã¹ã®IDã
mysecret-ããŒã¹ãã¢ããã®ãã¹ã¯ãŒãã 詳现ã«ã€ããŠã¯ãäžèšã®ããŒã«ã«èšŒææžã¹ãã¢ãžã®ãªã³ã¯ãåç §ããŠãã ããã
ãä»»æã®èšŒææžã§ä¿¡é Œããããéžæããå Žåã¯ã次ã®ããã«2ã€ã®ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããã ãã§ååã§ãã
private class DummyHostnameVerifier implements HostnameVerifier{ @Override public boolean verify(String hostname, SSLSession session) { return true; } } private class DummyTrustManager implements X509TrustManager{ @Override public void checkClientTrusted(...) throws CertificateException { //empty } @Override public void checkServerTrusted(...) throws CertificateException { //empty } ... }
次ã«ããããã®å®è£ ãHttpClientãŸãã¯HttpUrlConnectionã®ããããã«é©çšããå¿ èŠããããŸãã
ããããªãŒã¯ã©ãã§ããïŒ
ããããªãŒæ¶è²»ã¯ããµãŒããŒãšã®ç¢ºç«ãããæ¥ç¶ã®æ°ã«çŽæ¥äŸåããŸãã åã€ã³ã¹ããŒã«ã¯ãããããªãŒé»åãæ¶è²»ããç¡ç·ãã¢ã¯ãã£ãã«ããŸãã Androidã§ã¯ã€ã€ã¬ã¹ã©ãžãªãã©ã®ããã«æ©èœããããããªãŒã®æ¶è²»ã«ã©ã®ãããªåœ±é¿ããããã«ã€ããŠã¯ã次ã®èšäºãèªãããšããå§ãããŸãã
èšäºãèªãã åŸã䜿çšããããŒã«-HttpClientãŸãã¯HttpUrlConnectionãçåã«æãã§ãããã Androidéçºè ã¯ãæ°ããã¢ããªã±ãŒã·ã§ã³ã§HttpUrlConnectionã䜿çšããããšããå§ãããŸãã 䜿ãããããããã«éçºããããã©ãããã©ãŒã ã«é©åããŸãã äž»ã«ããŒãã¢ã©ã€ãæ¥ç¶ã®é倧ãªãã°ã®ãããAndroid 2.3ããåã®ãã©ãããã©ãŒã ã§ã¯HttpClientã䜿çšããå¿ èŠããããŸãã
ãã¡ãããã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³ãéçºããéã«ã¯ãããã3ã€ã®ç¹ãèæ ®ããŸãã ãããŠããŸã第äžã«ãããªãã¯ã©ãæããŸããïŒ