cronet

2025-12-07 0 276

cronet is a framework that using chromium net to send network request for android

Changelog

Current version 73.0.3653.5 released on 20th Jun 2019.

See details in CHANGELOG.

Examples

I have provided a sample.

See sample here on Github.

To run the sample application, simply clone this repository and use android studio to compile, install it on a connected device.

Feature

  • Full platform supports the latest version of TLS.
  • The platform supports the latest network protocols such as HTTP/2 and QUIC.

Usage

Maven

<dependency>
	<groupId>io.github.lizhangqu</groupId>
	<artifactId>cronet-native</artifactId>
	<version>73.0.3653.0.6</version>
</dependency>

Gradle

compile \'io.github.lizhangqu:cronet-native:73.0.3653.0.6\'

Remote so

The cronet\’s so file is big, you can use remote mode to reduce the apk size by exclude cronet-so module.

compile (\'io.github.lizhangqu:cronet-native:73.0.3653.0.6\'){
    exclude group: \'io.github.lizhangqu\', module: \'cronet-so\'
}

And add custom library loader when init cronet.

try {
    CronetEngine.Builder myBuilder = new CronetEngine.Builder(this);
    myBuilder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024)
            .setLibraryLoader(new ChromiumLibraryLoader(this)) //set library to such as ChromiumLibraryLoader impl
            .enableHttp2(true)
            .enableQuic(false);
    Log.i(TAG, \"setup\");
    CronetEngine cronetEngine = myBuilder.build();
} catch (Throwable e) {

}

You should use the httpurlconnection style api for downgrade

public HttpURLConnection createHttpURLConnection(CronetEngine cronetEngine String url) {
    try {
        return (HttpURLConnection) cronetEngine.openConnection(new URL(url));
    } catch (Exception e) {
        try {
            return (HttpURLConnection) new URL(url).openConnection();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    return null;
}


private void sendHeadRequestByHurl() {
    InputStream inputStream = null;
    try {
        HttpURLConnection urlConnection = createHttpURLConnection(cronetEngine, \"url\");
        urlConnection.setDoInput(true);
        urlConnection.setDoOutput(true);
        urlConnection.setRequestMethod(\"HEAD\");
        urlConnection.getOutputStream().write(\"a=b&b=c\".getBytes());
    
        Map<String, List<String>> headerFields = urlConnection.getHeaderFields();
    
        if (urlConnection.getResponseCode() >= HttpURLConnection.HTTP_BAD_REQUEST) {
            InputStream errorStream = urlConnection.getErrorStream();
            readInputStream(errorStream);
        } else {
            inputStream = urlConnection.getInputStream();
            readInputStream(inputStream);
           
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

NDK abiFilters

This library add all so default, if you need add only one, you should use ndk abiFilters yourself.

I suggest that you only add abiFilters \”armeabi-v7a\”.

android {
    defaultConfig {
        ndk {
            abiFilters \"armeabi-v7a\"
            
//          default is no filters       
//          abiFilters \"armeabi\"
//          abiFilters \"armeabi-v7a\"
//          abiFilters \"arm64-v8a\"
//          abiFilters \"x86\"
//          abiFilters \"x86_64\"
//          abiFilters \"mips\"
//          abiFilters \"mips64\"
        }
    }
}

Create Engine

CronetEngine.Builder builder = new CronetEngine.Builder(context);
builder.
        enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY,
                100 * 1024) // cache
        .enableHttp2(true)  // Http/2.0 Supprot
        .enableQuic(true)   // Quic Supprot
        .setHostResolver(new HostResolver() {
            @Override
            public List<InetAddress> resolve(String hostname) throws UnknownHostException {
                if (hostname == null)
                    throw new UnknownHostException(\"hostname == null\");
                return Arrays.asList(InetAddress.getAllByName(hostname));
            }
        })                  // custom dns, you can use httpdns here
        .enableSDCH(true)   // SDCH Supprot
        .setLibraryName(\"cronet\");  // lib so name
CronetEngine cronetEngine = builder.build();
//see more config in the code

Use For HttpUrlConnection

You can use the method like OkHttp

URL.setURLStreamHandlerFactory(new OkUrlFactory(new OkHttpClient()));

Cronet also support it.

CronetURLStreamHandlerFactory cronetURLStreamHandlerFactory = new CronetURLStreamHandlerFactory(cronetEngine);
URL.setURLStreamHandlerFactory(cronetURLStreamHandlerFactory);

And then you don\’t need to modify your java code like this.

try {
     URL url = new URL(mEditTextUrl.getText().toString());
     HttpURLConnection connection = (HttpURLConnection) url.openConnection();
     Log.e(\"TAG\", \"connection:\" + connection);
     connection.setDoInput(true);
     connection.setConnectTimeout(10000);
     connection.setReadTimeout(10000);
     connection.setRequestMethod(\"GET\");
     connection.connect();
     int responseCode = connection.getResponseCode();
     InputStream inputStream = connection.getInputStream();
     ByteArrayOutputStream output = new ByteArrayOutputStream();
     copy(inputStream, output);
     output.close();
     inputStream.close();
     byte[] bytes = output.toByteArray();
     String response = new String(bytes);
     Log.e(\"TAG\", \"responseCode:\" + responseCode);
     Log.e(\"TAG\", \"response body:\" + response);
 } catch (IOException e) {
     e.printStackTrace();
 }
 
 public static long copy(InputStream input, OutputStream output) throws IOException {
    return copyLarge(input, output, new byte[2048]);
 }
 
 public static long copyLarge(InputStream input, OutputStream output, byte[] buffer)
        throws IOException {
    long count = 0;
    int n = 0;
    while (-1 != (n = input.read(buffer))) {
        output.write(buffer, 0, n);
        count += n;
    }
    return count;
 }

Attentation Please

If you use the HttpURLConnection style api, you must read the inputstream anyway.

static ByteArrayInputStream toByteArrayInputStream(InputStream inputStream) {
    if (inputStream != null) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
            return new ByteArrayInputStream(outputStream.toByteArray());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    return null;
}

static void readInputStream(InputStream inputStream) {
    if (inputStream != null) {
        try {
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = inputStream.read(buffer)) != -1) {
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


InputStream inputStream = null;
try {
    inputStream = urlConnection.getInputStream();
} catch (IOException e) {
    inputStream = toByteArrayInputStream(urlConnection.getErrorStream());
}

//you must read the inputStream
readInputStream(inputStream);

Send GET Request

UrlRequest.Builder builder = new UrlRequest.Builder(mEditTextUrl.getText().toString(), new UrlRequest.Callback() {
     private ByteArrayOutputStream mBytesReceived = new ByteArrayOutputStream();
     private WritableByteChannel mReceiveChannel = Channels.newChannel(mBytesReceived);

     @Override
     public void onRedirectReceived(UrlRequest urlRequest, UrlResponseInfo urlResponseInfo, String s) throws Exception {
         Log.i(\"TAG\", \"onRedirectReceived\");
         urlRequest.followRedirect();
     }

     @Override
     public void onResponseStarted(UrlRequest urlRequest, UrlResponseInfo urlResponseInfo) throws Exception {
         Log.i(\"TAG\", \"onResponseStarted\");
         urlRequest.read(ByteBuffer.allocateDirect(32 * 1024));
     }

     @Override
     public void onReadCompleted(UrlRequest urlRequest, UrlResponseInfo urlResponseInfo, ByteBuffer byteBuffer) throws Exception {
         Log.i(\"TAG\", \"onReadCompleted\");
         byteBuffer.flip();

         try {
             mReceiveChannel.write(byteBuffer);
         } catch (IOException e) {
             e.printStackTrace();
         }
         byteBuffer.clear();
         urlRequest.read(byteBuffer);
     }

     @Override
     public void onSucceeded(UrlRequest urlRequest, UrlResponseInfo urlResponseInfo) {
         Log.i(\"TAG\", \"onSucceeded\");
         Log.i(\"TAG\", String.format(\"Request Completed, status code is %d, total received bytes is %d\",
                 urlResponseInfo.getHttpStatusCode(), urlResponseInfo.getReceivedBytesCount()));

         final String receivedData = mBytesReceived.toString();
         final String url = urlResponseInfo.getUrl();
         final String text = \"Completed \" + url + \" (\" + urlResponseInfo.getHttpStatusCode() + \")\";

         Log.i(\"TAG\", \"text:\" + text);
         Log.i(\"TAG\", \"receivedData:\" + receivedData);
         Handler handler = new Handler(Looper.getMainLooper());
         handler.post(new Runnable() {
             @Override
             public void run() {
                 Toast.makeText(getApplicationContext(), \"onSucceeded\", Toast.LENGTH_SHORT).show();
             }
         });
     }

     @Override
     public void onFailed(UrlRequest urlRequest, UrlResponseInfo urlResponseInfo, UrlRequestException e) {
         Log.i(\"TAG\", \"onFailed\");
         Log.i(\"TAG\", \"error is: %s\" + e.getMessage());

         Handler handler = new Handler(Looper.getMainLooper());
         handler.post(new Runnable() {
             @Override
             public void run() {
                 Toast.makeText(getApplicationContext(), \"onFailed\", Toast.LENGTH_SHORT).show();
             }
         });
     }
 }, executor, cronetEngine);
 builder.build().start();

Send POST Request

public void startWithURL(String url, UrlRequest.Callback callback, Executor executor, String postData) {
    UrlRequest.Builder builder = new UrlRequest.Builder(url, callback, executor, mCronetEngine);
    applyPostDataToUrlRequestBuilder(builder, executor, postData);
    builder.build().start();
}

private void applyPostDataToUrlRequestBuilder(
        UrlRequest.Builder builder, Executor executor, String postData) {
    if (postData != null && postData.length() > 0) {
        builder.setHttpMethod(\"POST\");
        builder.addHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");
        builder.setUploadDataProvider(
                UploadDataProviders.create(postData.getBytes()), executor);
    }
}

And then reuse the callback in Send GET Request

Thanks

  • chromium-net-android-porting
  • chromium-compile-guide-for-android
  • lazy-chromium-net-android-porting-guide
  • chromium-gn-build-tools

License

chromium net for android(cronet) is under the BSD license. See the LICENSE file for details.

下载源码

通过命令行克隆项目:

git clone https://github.com/lizhangqu/cronet.git

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 开发教程 cronet https://www.zuozi.net/31342.html

常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务