{"id":19483700,"url":"https://github.com/lizhangqu/cronet","last_synced_at":"2025-06-28T16:34:41.097Z","repository":{"id":142563463,"uuid":"93995106","full_name":"lizhangqu/cronet","owner":"lizhangqu","description":"cronet is a framework that using chromium net to send network request for android","archived":false,"fork":false,"pushed_at":"2019-11-23T05:43:21.000Z","size":105074,"stargazers_count":151,"open_issues_count":4,"forks_count":33,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-25T16:46:17.446Z","etag":null,"topics":["android","chromium","cronet","google","net"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lizhangqu.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-06-11T09:41:13.000Z","updated_at":"2025-03-26T02:54:54.000Z","dependencies_parsed_at":"2023-05-02T15:00:35.687Z","dependency_job_id":null,"html_url":"https://github.com/lizhangqu/cronet","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"purl":"pkg:github/lizhangqu/cronet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lizhangqu%2Fcronet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lizhangqu%2Fcronet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lizhangqu%2Fcronet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lizhangqu%2Fcronet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lizhangqu","download_url":"https://codeload.github.com/lizhangqu/cronet/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lizhangqu%2Fcronet/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262460498,"owners_count":23314750,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","chromium","cronet","google","net"],"created_at":"2024-11-10T20:16:23.993Z","updated_at":"2025-06-28T16:34:41.091Z","avatar_url":"https://github.com/lizhangqu.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"cronet is a framework that using chromium net to send network request for android\n====================================\n\n[ ![Download](https://api.bintray.com/packages/lizhangqu/maven/io.github.lizhangqu:cronet-api/images/download.svg) ](https://bintray.com/lizhangqu/maven/io.github.lizhangqu:cronet/_latestVersion)\n\nChangelog\n---------\n\nCurrent version 73.0.3653.5 released on 20th Jun 2019.\n\nSee details in [CHANGELOG](https://github.com/lizhangqu/cronet/blob/master/CHANGELOG.md).\n\n\nExamples\n--------\n\nI have provided a sample.\n\nSee sample [here on Github](https://github.com/lizhangqu/cronet/tree/master/app).\n\nTo run the sample application, simply clone this repository and use android studio to compile, install it on a connected device.\n\n\nFeature\n---------\n\n - Full platform supports the latest version of TLS.\n - The platform supports the latest network protocols such as HTTP/2 and QUIC.\n\nUsage\n-----\n\n**Maven**\n\n```\n\u003cdependency\u003e\n\t\u003cgroupId\u003eio.github.lizhangqu\u003c/groupId\u003e\n\t\u003cartifactId\u003ecronet-native\u003c/artifactId\u003e\n\t\u003cversion\u003e73.0.3653.0.6\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n**Gradle**\n\n```\ncompile 'io.github.lizhangqu:cronet-native:73.0.3653.0.6'\n```\n\n**Remote so**\n\nThe cronet's so file is big, you can use remote mode to reduce the apk size by exclude cronet-so module.\n\n```\ncompile ('io.github.lizhangqu:cronet-native:73.0.3653.0.6'){\n    exclude group: 'io.github.lizhangqu', module: 'cronet-so'\n}\n```\n\nAnd add custom library loader when init cronet.\n\n```\ntry {\n    CronetEngine.Builder myBuilder = new CronetEngine.Builder(this);\n    myBuilder.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024)\n            .setLibraryLoader(new ChromiumLibraryLoader(this)) //set library to such as ChromiumLibraryLoader impl\n            .enableHttp2(true)\n            .enableQuic(false);\n    Log.i(TAG, \"setup\");\n    CronetEngine cronetEngine = myBuilder.build();\n} catch (Throwable e) {\n\n}\n```\n\nYou should use the httpurlconnection style api for downgrade\n\n```\npublic HttpURLConnection createHttpURLConnection(CronetEngine cronetEngine String url) {\n    try {\n        return (HttpURLConnection) cronetEngine.openConnection(new URL(url));\n    } catch (Exception e) {\n        try {\n            return (HttpURLConnection) new URL(url).openConnection();\n        } catch (IOException ex) {\n            ex.printStackTrace();\n        }\n    }\n    return null;\n}\n\n\nprivate void sendHeadRequestByHurl() {\n    InputStream inputStream = null;\n    try {\n        HttpURLConnection urlConnection = createHttpURLConnection(cronetEngine, \"url\");\n        urlConnection.setDoInput(true);\n        urlConnection.setDoOutput(true);\n        urlConnection.setRequestMethod(\"HEAD\");\n        urlConnection.getOutputStream().write(\"a=b\u0026b=c\".getBytes());\n    \n        Map\u003cString, List\u003cString\u003e\u003e headerFields = urlConnection.getHeaderFields();\n    \n        if (urlConnection.getResponseCode() \u003e= HttpURLConnection.HTTP_BAD_REQUEST) {\n            InputStream errorStream = urlConnection.getErrorStream();\n            readInputStream(errorStream);\n        } else {\n            inputStream = urlConnection.getInputStream();\n            readInputStream(inputStream);\n           \n        }\n    } catch (Exception e) {\n        e.printStackTrace();\n    } finally {\n        if (inputStream != null) {\n            try {\n                inputStream.close();\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n        }\n    }\n}\n\n```\n\n**NDK abiFilters**\n\nThis library add all so default, if you need add only one, you should use ndk abiFilters yourself.\n\nI suggest that you only add **abiFilters \"armeabi-v7a\"**.\n\n```\nandroid {\n    defaultConfig {\n        ndk {\n            abiFilters \"armeabi-v7a\"\n            \n//          default is no filters       \n//          abiFilters \"armeabi\"\n//          abiFilters \"armeabi-v7a\"\n//          abiFilters \"arm64-v8a\"\n//          abiFilters \"x86\"\n//          abiFilters \"x86_64\"\n//          abiFilters \"mips\"\n//          abiFilters \"mips64\"\n        }\n    }\n}\n```\n\n**Create Engine**\n\n```\nCronetEngine.Builder builder = new CronetEngine.Builder(context);\nbuilder.\n        enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY,\n                100 * 1024) // cache\n        .enableHttp2(true)  // Http/2.0 Supprot\n        .enableQuic(true)   // Quic Supprot\n        .setHostResolver(new HostResolver() {\n            @Override\n            public List\u003cInetAddress\u003e resolve(String hostname) throws UnknownHostException {\n                if (hostname == null)\n                    throw new UnknownHostException(\"hostname == null\");\n                return Arrays.asList(InetAddress.getAllByName(hostname));\n            }\n        })                  // custom dns, you can use httpdns here\n        .enableSDCH(true)   // SDCH Supprot\n        .setLibraryName(\"cronet\");  // lib so name\nCronetEngine cronetEngine = builder.build();\n//see more config in the code\n```\n\n**Use For HttpUrlConnection**\n\nYou can use the method like OkHttp \n\n```\nURL.setURLStreamHandlerFactory(new OkUrlFactory(new OkHttpClient()));\n```\n\nCronet also support it.\n\n```\nCronetURLStreamHandlerFactory cronetURLStreamHandlerFactory = new CronetURLStreamHandlerFactory(cronetEngine);\nURL.setURLStreamHandlerFactory(cronetURLStreamHandlerFactory);\n```\n\nAnd then you don't need to modify your java code like this.\n\n```\ntry {\n     URL url = new URL(mEditTextUrl.getText().toString());\n     HttpURLConnection connection = (HttpURLConnection) url.openConnection();\n     Log.e(\"TAG\", \"connection:\" + connection);\n     connection.setDoInput(true);\n     connection.setConnectTimeout(10000);\n     connection.setReadTimeout(10000);\n     connection.setRequestMethod(\"GET\");\n     connection.connect();\n     int responseCode = connection.getResponseCode();\n     InputStream inputStream = connection.getInputStream();\n     ByteArrayOutputStream output = new ByteArrayOutputStream();\n     copy(inputStream, output);\n     output.close();\n     inputStream.close();\n     byte[] bytes = output.toByteArray();\n     String response = new String(bytes);\n     Log.e(\"TAG\", \"responseCode:\" + responseCode);\n     Log.e(\"TAG\", \"response body:\" + response);\n } catch (IOException e) {\n     e.printStackTrace();\n }\n \n public static long copy(InputStream input, OutputStream output) throws IOException {\n    return copyLarge(input, output, new byte[2048]);\n }\n \n public static long copyLarge(InputStream input, OutputStream output, byte[] buffer)\n        throws IOException {\n    long count = 0;\n    int n = 0;\n    while (-1 != (n = input.read(buffer))) {\n        output.write(buffer, 0, n);\n        count += n;\n    }\n    return count;\n }\n\n```\n\n**Attentation Please**\n\nIf you use the HttpURLConnection style api, you must read the inputstream anyway.\n\n```\nstatic ByteArrayInputStream toByteArrayInputStream(InputStream inputStream) {\n    if (inputStream != null) {\n        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();\n        try {\n            byte[] buffer = new byte[1024];\n            int len = -1;\n            while ((len = inputStream.read(buffer)) != -1) {\n                outputStream.write(buffer, 0, len);\n            }\n            return new ByteArrayInputStream(outputStream.toByteArray());\n        } catch (IOException e) {\n            e.printStackTrace();\n        } finally {\n            if (inputStream != null) {\n                try {\n                    inputStream.close();\n                } catch (Exception e) {\n                    e.printStackTrace();\n                }\n            }\n            if (outputStream != null) {\n                try {\n                    outputStream.close();\n                } catch (Exception e) {\n                    e.printStackTrace();\n                }\n            }\n        }\n    }\n    return null;\n}\n\nstatic void readInputStream(InputStream inputStream) {\n    if (inputStream != null) {\n        try {\n            byte[] buffer = new byte[1024];\n            int len = -1;\n            while ((len = inputStream.read(buffer)) != -1) {\n            }\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n}\n\n\nInputStream inputStream = null;\ntry {\n    inputStream = urlConnection.getInputStream();\n} catch (IOException e) {\n    inputStream = toByteArrayInputStream(urlConnection.getErrorStream());\n}\n\n//you must read the inputStream\nreadInputStream(inputStream);\n```\n\n\n**Send GET Request**\n\n```\nUrlRequest.Builder builder = new UrlRequest.Builder(mEditTextUrl.getText().toString(), new UrlRequest.Callback() {\n     private ByteArrayOutputStream mBytesReceived = new ByteArrayOutputStream();\n     private WritableByteChannel mReceiveChannel = Channels.newChannel(mBytesReceived);\n\n     @Override\n     public void onRedirectReceived(UrlRequest urlRequest, UrlResponseInfo urlResponseInfo, String s) throws Exception {\n         Log.i(\"TAG\", \"onRedirectReceived\");\n         urlRequest.followRedirect();\n     }\n\n     @Override\n     public void onResponseStarted(UrlRequest urlRequest, UrlResponseInfo urlResponseInfo) throws Exception {\n         Log.i(\"TAG\", \"onResponseStarted\");\n         urlRequest.read(ByteBuffer.allocateDirect(32 * 1024));\n     }\n\n     @Override\n     public void onReadCompleted(UrlRequest urlRequest, UrlResponseInfo urlResponseInfo, ByteBuffer byteBuffer) throws Exception {\n         Log.i(\"TAG\", \"onReadCompleted\");\n         byteBuffer.flip();\n\n         try {\n             mReceiveChannel.write(byteBuffer);\n         } catch (IOException e) {\n             e.printStackTrace();\n         }\n         byteBuffer.clear();\n         urlRequest.read(byteBuffer);\n     }\n\n     @Override\n     public void onSucceeded(UrlRequest urlRequest, UrlResponseInfo urlResponseInfo) {\n         Log.i(\"TAG\", \"onSucceeded\");\n         Log.i(\"TAG\", String.format(\"Request Completed, status code is %d, total received bytes is %d\",\n                 urlResponseInfo.getHttpStatusCode(), urlResponseInfo.getReceivedBytesCount()));\n\n         final String receivedData = mBytesReceived.toString();\n         final String url = urlResponseInfo.getUrl();\n         final String text = \"Completed \" + url + \" (\" + urlResponseInfo.getHttpStatusCode() + \")\";\n\n         Log.i(\"TAG\", \"text:\" + text);\n         Log.i(\"TAG\", \"receivedData:\" + receivedData);\n         Handler handler = new Handler(Looper.getMainLooper());\n         handler.post(new Runnable() {\n             @Override\n             public void run() {\n                 Toast.makeText(getApplicationContext(), \"onSucceeded\", Toast.LENGTH_SHORT).show();\n             }\n         });\n     }\n\n     @Override\n     public void onFailed(UrlRequest urlRequest, UrlResponseInfo urlResponseInfo, UrlRequestException e) {\n         Log.i(\"TAG\", \"onFailed\");\n         Log.i(\"TAG\", \"error is: %s\" + e.getMessage());\n\n         Handler handler = new Handler(Looper.getMainLooper());\n         handler.post(new Runnable() {\n             @Override\n             public void run() {\n                 Toast.makeText(getApplicationContext(), \"onFailed\", Toast.LENGTH_SHORT).show();\n             }\n         });\n     }\n }, executor, cronetEngine);\n builder.build().start();\n```\n\n**Send POST Request**\n\n```\npublic void startWithURL(String url, UrlRequest.Callback callback, Executor executor, String postData) {\n    UrlRequest.Builder builder = new UrlRequest.Builder(url, callback, executor, mCronetEngine);\n    applyPostDataToUrlRequestBuilder(builder, executor, postData);\n    builder.build().start();\n}\n\nprivate void applyPostDataToUrlRequestBuilder(\n        UrlRequest.Builder builder, Executor executor, String postData) {\n    if (postData != null \u0026\u0026 postData.length() \u003e 0) {\n        builder.setHttpMethod(\"POST\");\n        builder.addHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n        builder.setUploadDataProvider(\n                UploadDataProviders.create(postData.getBytes()), executor);\n    }\n}\n```\n\nAnd then reuse the callback in **Send GET Request**\n\nThanks\n-------\n\n - [chromium-net-android-porting](http://hanpfei.github.io/2016/10/18/chromium-net-android-porting/)\n - [chromium-compile-guide-for-android](http://hanpfei.github.io/2016/10/16/Chromium_Android%E7%BC%96%E8%AF%91%E6%8C%87%E5%8D%97/)\n - [lazy-chromium-net-android-porting-guide](http://hanpfei.github.io/2016/11/11/lazy-chromium-net-android-porting-guide/)\n - [chromium-gn-build-tools](http://hanpfei.github.io/2016/11/16/ChromiumGN%E6%9E%84%E5%BB%BA%E5%B7%A5%E5%85%B7%E7%9A%84%E4%BD%BF%E7%94%A8/)\n\nLicense\n--------\nchromium net for android(cronet) is under the BSD license. See the [LICENSE](https://github.com/lizhangqu/chromium-net-for-android/blob/master/LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flizhangqu%2Fcronet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flizhangqu%2Fcronet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flizhangqu%2Fcronet/lists"}