LoginSignup
1
0

More than 3 years have passed since last update.

Google製 通信ライブラリ Cronet

Last updated at Posted at 2020-07-05

Cronetとは

Google製の通信ライブラリ
https://developer.android.com/guide/topics/connectivity/cronet?hl=ja
Sample
https://github.com/GoogleChromeLabs/cronet-sample

AndroidDeveloperによると、YoutubeなどGoogleアプリで使われているとのことでした。

Retrofit + Okhttp一強の時代(だと思っている)ですが
他のネットワーク系のライブラリに触れる機会がなかったので勉強がてらに触ってみました。

使い方

ともあれ早速使ってみましょう!

サンプルのリポジトリには、ソースをcloneして使ってくれとあるのですが、mavenリポジトリに登録がありました。
https://mvnrepository.com/artifact/com.google.android.gms/play-services-cronet

dependencies {
    api "com.google.android.gms:play-services-cronet:18.0.0"
}

今回APIは、Qiita API v2を利用しました。
Sampleにあったものは画像をそのままロードするようなものだったのですが、これは文字列を最終的に取り出してみました。

UrlRequest.Callbackを継承したCronetCallbackクラスでネットワークの通信状態を受け取ります。
onSucceededメソッドで最終的にJSONの文字列を受け取ります。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Cronet準備
        CronetEngine.Builder engineBuilder = new CronetEngine.Builder(getApplicationContext());
        //  HTTP/2とQiucでの通信を許可
        engineBuilder.enableHttp2(true).enableQuic(true);
        CronetEngine engine = engineBuilder.build();

     // 通信をするExecutorを指定できる
        // これは一つのスレッドですが、複数のスレッドを指定することができそうです
        Executor executor = Executors.newSingleThreadExecutor();
        CronetCallback callback = new CronetCallback();
        UrlRequest.Builder requestBuilder = engine.newUrlRequestBuilder(
                "https://qiita.com/api/v2/items", callback, executor);
        UrlRequest request = requestBuilder.build();

        // リクエスト開始
        request.start();
    }

    /**
     * onResponseStarted
     * onReadCompleted
     * onSucceeded の順で呼ばれる
     * 次のメソッドを通知したい場合、オーバーライドしたメソッドでrequest.read(byteBuffer)を呼ぶ
     */
    private class CronetCallback extends UrlRequest.Callback {

        private ByteArrayOutputStream bytesReceived = new ByteArrayOutputStream();
        private WritableByteChannel receiveChannel = Channels.newChannel(bytesReceived);

        @Override
        public void onRedirectReceived(UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
            Log.d("CronetCallback", "onRedirectReceived");
            // リダレクトを許可する場合
            request.followRedirect();

            // リダイレクトを許可しない場合
            // request.cancel();
        }

        @Override
        public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
            Log.d("CronetCallback", "onResponseStarted");
            int statusCode = info.getHttpStatusCode();
            // ステータスコードが200系だったので中身をリードする
            if (statusCode <= 200 && statusCode < 300) {
                request.read(ByteBuffer.allocateDirect(32 * 1024));
            } else {
                // ステータスコードが200系以外
            }
        }

        @Override
        public void onReadCompleted(UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer) {
            // リクエスト完了
            Log.d("CronetCallback", "onReadCompleted");
            byteBuffer.flip();
            try {
                receiveChannel.write(byteBuffer);
            } catch (IOException e) {
            }
            byteBuffer.clear();
            request.read(byteBuffer);
        }

        @Override
        public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
            // リクエスト成功
            Log.d("CronetCallback", "onSucceeded");
            byte[] byteArray = bytesReceived.toByteArray();
            String json = new String(byteArray);
            Log.d("CronetCallback", "json " + json);
        }

        @Override
        public void onFailed(UrlRequest request, UrlResponseInfo info, CronetException error) {
            Log.d("CronetCallback", "onFailed : " + error.getMessage());
        }
    }
}

余談

Exoplayerにも通信部分をCronetで行うextensionsが追加されています。
実際にこのextensionsを使ってみたところ、Explayerのサンプル動画が再生できました。(okhttp版もあります)
https://github.com/google/ExoPlayer/tree/release-v2/extensions/cronet

所感

リダイレクトの指定があったら、レスポンスを受け取った時にステータスコードをみて次の処理に飛ばすか
などあり、その点便利かなと思いました。
そしてやっぱretrofitすごい

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0