[iOSとAndroid機能比較] 非同期通信
非同期通信
今回は非同期通信の処理を比較してみます。外部ライブラリ等を使わずに素手で殴りあってみます。
目標
「指定したURLのコンテンツを非同期通信にて取得」してLoggerに表示することが目標です
iOS7の場合
iOS7は、NSURLSessionTask クラスを利用します。
詳しくはCMの【iOSハンター(HR.2、武器:太刀)】平井祐樹のエントリから一部借用します。
iOS7において、非同期通を行い、指定したURLからコンテンツを取得するコードは次の通りです。
NSURLSession *session = [NSURLSession sharedSession]; // URL NSURL *url = [NSURL URLWithString:@"https://classmethod.jp/"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; // 非同期処理のタスク NSURLSessionTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (error) { // 通信が異常終了したときの処理 return; } // 通信が正に常終了したときの処理 NSLog(@"data : %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); }]; // 通信開始 [task resume];
これだけで、指定したURLから非同期でコンテンツを取得することができるようです
Androidの場合
Androidは非同期通信を行う場合は、いくつか方法があると思いますが、今回はAsyncTaskLoaderとDefaultHttpClientを利用した通信手法を実装してみます
AsyncTaskLoaderの使い方は、こちらを参照してください
非同期通信を行うAsyncTaskLoaderクラスは以下のとおり
package jp.classmethod.android.sampleasyncapp; import android.content.AsyncTaskLoader; import android.content.Context; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import java.io.IOException; /** * ネットワーク通信のためのAsyncTaskLoader * Created by komuro on 2013/09/18. */ public class NetworkAsyncTaskLoader extends AsyncTaskLoader<String> { private HttpClient httpClient; private String url; /** * Constructor * @param context */ public NetworkAsyncTaskLoader(Context context, String url) { super(context); this.url = url; forceLoad(); } @Override public String loadInBackground() { httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url); try { return httpClient.execute(httpGet, new ResponseHandler<String>() { @Override public String handleResponse(HttpResponse httpResponse) throws ClientProtocolException, IOException { int status = httpResponse.getStatusLine().getStatusCode(); switch (status) { case HttpStatus.SC_OK: String result = EntityUtils.toString(httpResponse.getEntity(), "UTF-8"); return result; default: return null; } } }); } catch (ClientProtocolException e) { e.printStackTrace(); return null; } catch (IOException e) { e.printStackTrace(); return null; } finally { httpClient.getConnectionManager().shutdown(); } } }
Androidの非同期通信の場合は、汎用的な目的に利用できるAsyncTaskLoaderに、通信という目的を持たせるためのコードを書く必要がありますね
結果
双方とも期待どおり、非同期で通信を行いコンテンツを取得できたようです。以下結果です
iOS7
シミュレータを起動し、ボタンを押すと、以下のようなログが表示されました
Android
Androidは自前のXPERIA Zグローバル版をつなぎ実行します。ボタンを押すと以下の様なログが表示されました
まとめ
今回は非同期通信処理の実装について比較してみました。
iOS7の方が目的に特化しているクラスであるため、単純な比較は難しいですが、やはりAndroid側のクラスは汎用的に使えるようにしているためか、記述するコード量は多い印象です。
今回は非同期通信について、素手で殴りあってもらいました。コスト、工数、コード量等の観点から見ると、結果としての勝利はiOS側でしょうか。柔軟性といった要素が入ってくるとまた別かもしれません
Androidも外部ライブラリを使うことで、かなりドーピングができるはずなので(VolleyやAquery等)、こちらもドーピング後の再戦をしてみると、また少し結果が違うかもしれませぬ
iOSでコードをAndroidと同じ目的を達するコードを書いてみると、え?これだけ?と思うようなコード量で目的が達成してしまうことがしばしばあるため、いちいちカルチャーショックを受ける今日このごろです。ほぼほぼコーディングなしでここまで出来るとは。iOS, Xcode恐るべし