AndroidAsync Documentation

repository·master·Indexed 27 days ago

https://github.com/koush/androidasync

A low-level network protocol library for Android based on NIO, providing raw Socket, HTTP(s) client/server, and WebSocket client/server capabilities. It includes features for asynchronous downloads, multipart/form-data uploads, response caching, and middleware for intercepting HTTP lifecycle events. The library supports Kotlin Coroutines via the androidasync-kotlin dependency and utilizes Futures for asynchronous operations.

Tokens
4.3K
Snippets
10
Records
17
Agent score
93%

What's inside AndroidAsync

  1. Install androidasync-kotlin

    master

    To add Kotlin Coroutine support for AndroidAsync and Ion to your project, add the following dependency to your build configuration.

    <dependency>
        <groupId>com.koushikdutta.async</groupId>
        <artifactId>androidasync-kotlin</artifactId>
        <version>(insert latest version)</version>
    </dependency>
    dependencies {
        compile 'com.koushikdutta.async:androidasync-kotlin:<insert latest version>'
    }
  2. Install AndroidAsync via Maven or Gradle

    master

    You can add AndroidAsync to your project using Maven or Gradle. For Maven, use the com.koushikdutta.async groupId. For Gradle, use the 2.+ version range.

    <dependency>
        <groupId>com.koushikdutta.async</groupId>
        <artifactId>androidasync</artifactId>
        <version>(insert latest version)</version>
    </dependency>
    dependencies {
        compile 'com.koushikdutta.async:androidasync:2.+'
    }
  3. Use Kotlin Coroutines with AndroidAsync and Ion

    master

    Since AndroidAsync and Ion operations return futures, you can use the .await() extension function within a Kotlin suspend function to handle asynchronous operations sequentially or concurrently.

    // Sequential execution: each request waits for the previous one to finish
    suspend fun getTheRobotsTxt() {
      val googleRobots = Ion.with(context)
      .load("https://google.com/robots.txt")
      .asString()
      .await()
    
      val githubRobots = Ion.with(context)
      .load("https://github.com/robots.txt")
      .asString()
      .await()
    
      return googleRobots + githubRobots
    }
    
    // Concurrent execution: both requests are started before awaiting results
    suspend fun getTheRobotsTxt() {
      val googleRobots = Ion.with(context)
      .load("https://google.com/robots.txt")
      .asString()
    
      val githubRobots = Ion.with(context)
      .load("https://github.com/robots.txt")
      .asString()
    
      return googleRobots.await() + githubRobots.await()
    }
  4. Configure Response Caching

    master

    Enable caching for your AsyncHttpClient using ResponseCacheMiddleware.addCache. You must provide the client instance, a directory for cache files, and the maximum cache size in bytes.

    // arguments are the http client, the directory to store cache files,
    // and the size of the cache in bytes
    ResponseCacheMiddleware.addCache(AsyncHttpClient.getDefaultInstance(),
                                      getFileStreamPath("asynccache"),
                                      1024 * 1024 * 10);
  5. Perform multipart/form-data uploads

    master

    To upload files or form data, create an AsyncHttpPost object, populate a MultipartFormDataBody with your parts, and execute the request using AsyncHttpClient.

    AsyncHttpPost post = new AsyncHttpPost("http://myservercom/postform.html");
    MultipartFormDataBody body = new MultipartFormDataBody();
    body.addFilePart("my-file", new File("/path/to/file.txt");
    body.addStringPart("foo", "bar");
    post.setBody(body);
    AsyncHttpClient.getDefaultInstance().executeString(post, new AsyncHttpClient.StringCallback(){
            @Override
            public void onCompleted(Exception ex, AsyncHttpResponse source, String result) {
                if (ex != null) {
                    ex.printStackTrace();
                    return;
                }
                System.out.println("Server says: " + result);
            }
        });
  6. Create a WebSocket Client

    master

    Connect to a WebSocket server using AsyncHttpClient.websocket(). You can send both Strings and byte arrays, and set callbacks for receiving String data or raw byte data.

    AsyncHttpClient.getDefaultInstance().websocket(get, "my-protocol", new WebSocketConnectCallback() {
        @Override
        public void onCompleted(Exception ex, WebSocket webSocket) {
            if (ex != null) {
                ex.printStackTrace();
                return;
            }
            webSocket.send("a string");
            webSocket.send(new byte[10]);
            webSocket.setStringCallback(new StringCallback() {
                public void onStringAvailable(String s) {
                    System.out.println("I got a string: " + s);
                }
            });
            webSocket.setDataCallback(new DataCallback() {
                public void onDataAvailable(DataEmitter emitter, ByteBufferList byteBufferList) {
                    System.out.println("I got some bytes!");
                    // note that this data has been read
                    byteBufferList.recycle();
                }
            });
        }
    });
  7. Create an HTTP Server

    master

    You can host a simple HTTP server using AsyncHttpServer. Define routes using methods like .get() and provide an HttpServerRequestCallback to handle requests and send responses.

    AsyncHttpServer server = new AsyncHttpServer();
    
    List<WebSocket> _sockets = new ArrayList<WebSocket>();
    
    server.get("/", new HttpServerRequestCallback() {
        @Override
        public void onRequest(AsyncHttpServerRequest request, AsyncHttpServerResponse response) {
            response.send("Hello!!!");
        }
    });
    
    // listen on port 5000
    server.listen(5000);
  8. Use Futures for asynchronous operations

    master

    All API calls in AndroidAsync return a Future. You can either block and wait for the result using .get() (which may throw an exception) or attach a FutureCallback to handle the result asynchronously.

    // Blocking approach
    Future<String> string = client.getString("http://foo.com/hello.txt");
    String value = string.get();
    
    // Callback approach
    client.getString("http://foo.com/hello.txt")
    .setCallback(new FutureCallback<String>() {
        @Override
        public void onCompleted(Exception e, String result) {
            System.out.println(result);
        }
    });
  9. Create a WebSocket Server

    master

    Use AsyncHttpServer to host a WebSocket endpoint. Use .websocket() to define the path and a WebSocketRequestCallback to handle new connections. You can manage active connections in a list and broadcast messages to them.

    AsyncHttpServer httpServer = new AsyncHttpServer();
    
    httpServer.listen(AsyncServer.getDefault(), port);
    
    httpServer.websocket("/live", new AsyncHttpServer.WebSocketRequestCallback() {
        @Override
        public void onConnected(final WebSocket webSocket, AsyncHttpServerRequest request) {
            _sockets.add(webSocket);
            
            //Use this to clean up any references to your websocket
            webSocket.setClosedCallback(new CompletedCallback() {
                @Override
                public void onCompleted(Exception ex) {
                    try {
                        if (ex != null)
                            Log.e("WebSocket", "An error occurred", ex);
                    } finally {
                        _sockets.remove(webSocket);
                    }
                }
            });
            
            webSocket.setStringCallback(new StringCallback() {
                @Override
                public void onStringAvailable(String s) {
                    if ("Hello Server".equals(s))
                        webSocket.send("Welcome Client!");
                }
            });
        }
    });
    
    //..Sometime later, broadcast!
    for (WebSocket socket : _sockets)
        socket.send("Fireball!");
  10. Download a URL to a String, JSON, or File

    master

    Use AsyncHttpClient.getDefaultInstance() to perform asynchronous downloads. You can retrieve data as a raw String, a JSONObject, a JSONArray, or save it directly to a File using specific callbacks.

    // Download to String
    AsyncHttpClient.getDefaultInstance().getString(url, new AsyncHttpClient.StringCallback() {
        @Override
        public void onCompleted(Exception e, AsyncHttpResponse response, String result) {
            if (e != null) {
                e.printStackTrace();
                return;
            }
            System.out.println("I got a string: " + result);
        }
    });
    
    // Download JSON Object
    AsyncHttpClient.getDefaultInstance().getJSONObject(url, new AsyncHttpClient.JSONObjectCallback() {
        @Override
        public void onCompleted(Exception e, AsyncHttpResponse response, JSONObject result) {
            if (e != null) {
                e.printStackTrace();
                return;
            }
            System.out.println("I got a JSONObject: " + result);
        }
    });
    
    // Download to File
    AsyncHttpClient.getDefaultInstance().getFile(url, filename, new AsyncHttpClient.FileCallback() {
        @Override
        public void onCompleted(Exception e, AsyncHttpResponse response, File result) {
            if (e != null) {
                e.printStackTrace();
                return;
            }
            System.out.println("my file is available at: " + result.getAbsolutePath());
        }
    });
  11. Inspect ResponseHead data in middleware

    master

    Within the exchangeHeaders hook, you can access the ResponseHead object via OnExchangeHeaderData.response. The ResponseHead interface allows you to inspect and manipulate the response metadata:

    • code(): Returns the HTTP status code.
    • message(): Returns the HTTP status message.
    • protocol(): Returns the protocol string.
    • headers(): Returns the Headers object.
    • sink(): Access the DataSink for the response.
    • emitter(): Access the DataEmitter for the response.

    Methods like code(int), message(String), protocol(String), headers(Headers), sink(DataSink), and emitter(DataEmitter) allow you to modify these properties.