• Stars
    star
    135
  • Rank 260,117 (Top 6 %)
  • Language
    Java
  • License
    BSD 3-Clause "New...
  • Created almost 7 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

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

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

Download

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

License

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

More Repositories

1

CoreLink

Android 开发中的日常积累
Java
2,724
star
2

CoreProgress

OkHttp upload and download progress support
Java
517
star
3

Camera

二代身份证信息识别
Java
370
star
4

PinyinIME

google 拼音输入法 android studio可编译
C++
196
star
5

dlfcn_compat

兼容Android 7.0 dlfcn(dlopen、dlsym、dlclose、dlerror)
C++
141
star
6

CoreUtil

CoreUtil is an android tools library which contains some useful utilities
Java
113
star
7

CorePage

Corepage is a page switch framework based on Fragment
Java
108
star
8

AndroidGradlePluginCodeViewer

83
star
9

QuickMultidex

一种在Dalvik虚拟机上多Dex首次加载的优化方案,支持4.1~4.4
Java
74
star
10

android-bundle-support

增强型apk analyzer,支持ap_, ap, aar, aab, jar, so, awb, aab, apks等zip文件使用apk analyzer打开, android studio插件
Java
60
star
11

plugin-veridex

android 私有api调用检测
Groovy
56
star
12

AndroidGradlePluginCompat

android gradle plugin兼容库
Groovy
55
star
13

TensorflowLite

Tensorflow Lite Android Library
Java
41
star
14

OpenAtlasDemo

OpenAtlasDemo
Java
33
star
15

NDKMemoryLeakSample

NDK内存泄露检测
C++
32
star
16

aapt-cmake-buildscript

aapt cmake构建系统,支持mac和linux(ubuntu 16.0.4)构建,支持linux(ubuntu 16.0.4)交叉编译windows版本,支持x86和x86_64构建
CMake
29
star
17

android-gradle-plugin-transform-patch

android gradle plugin transform patch
Groovy
28
star
18

dexdeps

查看dex中class, field, method内部与外部依赖
Java
24
star
19

VoiceAndVideo

即时音视频解决方案
Java
24
star
20

zafu_jwc

正方教务课程表抓取
Java
23
star
21

MultiChannel

多渠道打包Gradle插件
Groovy
22
star
22

AndroidScreenAdapter

a tool which adapts android screens
Java
22
star
23

flutter_lldb

flutter engine remote debug with lldb
Python
22
star
24

plugin-flutter-patch

flutter patch generator in gradle
Java
22
star
25

HttpDNS

修改自新浪HttpDNSLib,改项目结构为Android Studio gradle项目,底层请求使用OkHTTP
Java
22
star
26

QFix

Java
20
star
27

plugin-flutter-armeabi

flutter armeabi兼容
Groovy
20
star
28

flutter_engine_build

Flutter Engine构建产物归档
Python
19
star
29

PriorityOkHttp

支持优先级调度的OkHttp
Java
19
star
30

CorePublish

maven发布插件和bintray发布插件
Groovy
18
star
31

CorePatch

An universal patch generator and applier such as using BsDiff/BsPatch and Google Archive Patch
Java
17
star
32

aapt-repo-manifest

aapt cmake 构建 核心repo manifest, 支持mac和linux(ubuntu 16.0.4)构建,支持linux(ubuntu 16.0.4)交叉编译windows的版本
17
star
33

Base

a library for some base code,such as BaseAdapter,BaseActivity,BaseFragement
Java
15
star
34

FrescoLoader

FrescoLoader is a framework which use fresco to load image into android.widget.ImageView.
Java
14
star
35

CurlForAndroid

curl 移植到andorid ,支持https和http2.0
C++
14
star
36

NativeCompile

android 动态库远程依赖
Groovy
13
star
37

FastMultidex

multidex debug 构建提速
Groovy
12
star
38

plugin-api-detect

通用的api调用检测
Java
9
star
39

plugin-apache-httpclient-detect

a plugin to detect apache httpclient class calling
Groovy
8
star
40

flutter_app_for_lldb

调试用demo
Dart
8
star
41

netease

高仿网易新闻客户端主界面,使用DrawerLayout+ToolBar实现双向侧滑
Java
7
star
42

support-application

Global Application Getter Support, Env Support, Lifecycle Support And Route Support
Java
7
star
43

gradleJNI

使用Gradle与JNI结合的项目
Java
6
star
44

R8BugTest

reproduce r8 bug
Java
6
star
45

lizhangqu.github.io

个人博客
HTML
6
star
46

ZafuNews

浙江农林大学新闻网客户端阅读器,http://news.zafu.edu.cn
Java
5
star
47

gradle-wrapper

自定义的gradle-wrapper
Java
5
star
48

SimpleHtmlDom

php使用simple_html_dom抓取网页数据的一个Demo
PHP
4
star
49

ClassRemapper

class's package name remapper using javassist
Java
3
star
50

libuvSample

C++
2
star
51

LearningGradle

Gradle学习历程
2
star
52

common-gradle

gradle 公共脚本
2
star
53

spring-boot-study

spring boot 学习项目
Java
1
star
54

booster-test

booster 测试
Java
1
star
55

AndroidTools

安卓工具类
Java
1
star
56

CoreJNI

Android JNI开发积累
C++
1
star
57

Stetho

安卓 debug工具的使用
Java
1
star
58

EngineerCar

华立工程车项目,基于nfc刷卡路检
Java
1
star
59

AndroidGradlePluginSamples

Android Gradle Plugin代码碎片
Groovy
1
star