Building a Simple Static Server in an Android App for React Native

Building a Simple Static Server in an Android App for React Native
Photo by Karsten Winegeart / Unsplash

If you're developing a React Native app and need to serve static assets such as images and HTML files, you may encounter challenges, as React Native apps typically don't serve any backend. In such cases, a simple static server running within your Android app can be very useful.

1. Setup

First, add the NanoHTTPD dependency to your project's build.gradle file:

dependencies {
    implementation 'org.nanohttpd:nanohttpd:2.3.1'
}

This will automatically download and include NanoHTTPD in your project.

2. Creating the Static Server

Now, let's create a class that extends NanoHTTPD and overrides the serve() method to serve static files from your app's assets directory.

import android.content.Context;
import java.io.IOException;
import java.io.InputStream;
import fi.iki.elonen.NanoHTTPD;

public class StaticServer extends NanoHTTPD {

    private Context context;

    public StaticServer(Context context) {
        super(8080); // You can change the port number if needed
        this.context = context;
    }

    @Override
    public Response serve(IHTTPSession session) {
        String uri = session.getUri();
        try {
            InputStream inputStream = context.getAssets().open(uri.substring(1));
            return newChunkedResponse(Response.Status.OK, getMimeType(uri), inputStream);
        } catch (IOException e) {
            return newFixedLengthResponse(Response.Status.NOT_FOUND, NanoHTTPD.MIME_PLAINTEXT, "File not found");
        }
    }

    private String getMimeType(String uri) {
        if (uri.endsWith(".html")) {
            return "text/html";
        } else if (uri.endsWith(".css")) {
            return "text/css";
        } else if (uri.endsWith(".js")) {
            return "application/javascript";
        } else if (uri.endsWith(".png")) {
            return "image/png";
        } else if (uri.endsWith(".jpg") || uri.endsWith(".jpeg")) {
            return "image/jpeg";
        } else {
            return "text/plain";
        }
    }
}

3. Starting the Server

Finally, start the server in your activity's onCreate() method and stop it in the onDestroy() method.

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private StaticServer server;

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

        server = new StaticServer(getApplicationContext());
        try {
            server.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (server != null) {
            server.stop();
        }
    }
}

Conclusion

You've successfully created a simple static server in your Android app! This server can serve static files such as HTML, CSS, JavaScript, images, etc., directly from your app's assets directory. This approach is particularly convenient for React Native apps that have a lot of static assets to serve, as bundling them during build time may not be ideal due to various reasons, and dynamic importing might not be feasible.

Stay tuned for our upcoming blog post on setting up a similar static server in an iOS app!

Subscribe to Post, Code and Quiet Time.

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe