Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Android support (issues #103 #132 #406) #426

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 36 additions & 0 deletions android-template/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# The user should review this list, because some of this files can be keep
# inside their git repo when working in a real project. They are excluded
# here only to keep webview repo light.

# IDE stuff (usually some of these files are kept in real projects!)
.idea/
gradlew
gradlew.bat
gradle-wrapper.jar
gradle-wrapper.properties

# User stuff
local.properties

# Generated files
.DS_Store
/build
app/.cxx

# Gradle
.gradle

# Gradle and Maven with auto-import
*.iml
*.ipr

# Google
.google/

# Eclipse
.classpath
.project
org.eclipse.buildship.core.prefs

# Other
.ionide
40 changes: 40 additions & 0 deletions android-template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Native Activity Webview Template

This sample uses JNI to instantiate an Android Webview from C code.

## Requisites

- [Android Studio](http://developer.android.com/sdk/index.html)
- [Android NDK](https://developer.android.com/ndk/)
- [CMake plugin](http://tools.android.com/tech-docs/external-c-builds)

## Instructions

1. Place `webview.h` inside `app/src/main/cpp` directory.
2. Place custom code (eg. `main.cpp`) in the same folder.
3. Open project with Android Studio.
4. Set NDK in `File/Project Structure...`.
5. Sync Project with Gradle Files.
6. Connect a device with ADB.
7. Compile and run.

## Implementation

Code written by the user should contain at least the following lines:

```cpp
#include "webview.h"

ifdef ANDROID
int android_main(void *android_app) {
webview::webview w(true, android_app);
#else
int main() {
webview::webview w(true, nullptr);
#endif
/* user code goes here! */
return 0;
}
```

Android entrypoint `android_main` is expected by the library.
1 change: 1 addition & 0 deletions android-template/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
27 changes: 27 additions & 0 deletions android-template/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 29
ndkVersion '21.2.6472646'

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
defaultConfig {
applicationId 'ar.net.rainbyte.webview'
minSdkVersion 14
targetSdkVersion 29
versionCode 1
versionName "0.0.1"
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
}
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
24 changes: 24 additions & 0 deletions android-template/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ar.net.rainbyte.webview">

<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:hasCode="true"
android:theme="@android:style/Theme.DeviceDefault.NoActionBar">
<activity android:name="android.app.NativeActivity"
android:label="NativeActivity">
<meta-data android:name="android.app.lib_name"
android:value="webview-android-jni" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
28 changes: 28 additions & 0 deletions android-template/app/src/main/assets/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello Webview for Android</title>
<script>
window.onload = function() {
console.log('Onload started');
document.querySelector('h1').style.background = 'fuchsia';
document.querySelector('h1').innerText = `hello, ${navigator.userAgent}`;
noop('hello').then(function(res) {
console.log('noop res', res);
});
foo(1, 2).then(function(res) {
console.log('add res', res);
});
console.log('Onload finished');
}
</script>
</head>
<body style="height: 100vh; margin: 0;">
<h1>Hello NativeActivity Webview!</h1>
<noscript>
<h2>JS not supported :(</h2>
</noscript>
</body>
</html>
12 changes: 12 additions & 0 deletions android-template/app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.4.1)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -Wall -Werror")

add_library(webview-android-jni SHARED
main.cpp
webview.h)

# Include libraries needed for hello-jni lib
target_link_libraries(webview-android-jni
android
log)
30 changes: 30 additions & 0 deletions android-template/app/src/main/cpp/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "webview.h"

#ifdef ANDROID
int android_main(void *android_app) {
webview::webview w(true, android_app);
#elif WIN32
int WINAPI WinMain(HINSTANCE hInt, HINSTANCE hPrevInst, LPSTR lpCmdLine,
int nCmdShow) {
webview::webview w(true, nullptr);
#else
int main() {
webview::webview w(true, nullptr);
#endif
w.init("(function() { console.log('this is init 1, inside function'); })()");
w.set_title("Minimal example"); // ignored, not implemented yet
w.set_size(480, 320, WEBVIEW_HINT_NONE); // ignored, not implemented yet
w.init("console.log('this is init 2');");
w.bind("noop", [](std::string noopMsg) -> std::string {
return noopMsg;
});
w.bind("foo", [&w](std::string fooMsg) -> std::string {
w.eval("document.querySelector('h1').style.background = 'green';");
return fooMsg;
});
w.init("console.log('this is init 3');");
w.navigate("index.html");
w.eval("console.log('this is eval');");
w.run();
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ar.net.rainbyte.webview;

import android.webkit.JavascriptInterface;

public class ExternalInvoker {
private NativeFunction mCallback;

public ExternalInvoker(long funPtr) {
mCallback = new NativeFunction(funPtr);
}

@JavascriptInterface
public void invoke(String msg) {
mCallback.run(msg);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ar.net.rainbyte.webview;

public class NativeFunction {
static {
System.loadLibrary("webview-android-jni");
}
public native void runFunction(long funPtr, Object ... args);

long mFunPtr;

public NativeFunction(long funPtr) {
mFunPtr = funPtr;
}

public void run(Object ... args) {
runFunction(mFunPtr, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="28.575"
android:viewportHeight="28.575">
<path
android:pathData="M0,0h28.575v28.575h-28.575z"
android:strokeWidth="0.642903"
android:fillColor="#00ffff"
android:strokeColor="#00000000"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="28.575"
android:viewportHeight="28.575">
<path
android:pathData="m8.1699,15.7075v-1.4432h-1.4671v1.4432h-0.7049v-3.3668h0.7049v1.3405h1.4671v-1.3405h0.7049v3.3668z"
android:strokeWidth="0.0849532"
android:fillColor="#ff00ff"
android:strokeColor="#000000"/>
<path
android:pathData="m9.5319,15.7075v-3.3668h2.6475v0.5448L10.2368,12.8855v0.8459h1.7969v0.5448L10.2368,14.2762v0.8865h2.0406v0.5448z"
android:strokeWidth="0.0849532"
android:fillColor="#ff00ff"
android:strokeColor="#000000"/>
<path
android:pathData="m12.7959,15.7075v-3.3668h0.7049v2.8219h1.8064v0.5448z"
android:strokeWidth="0.0849532"
android:fillColor="#ff00ff"
android:strokeColor="#000000"/>
<path
android:pathData="m15.7851,15.7075v-3.3668h0.7049v2.8219h1.8064v0.5448z"
android:strokeWidth="0.0849532"
android:fillColor="#ff00ff"
android:strokeColor="#000000"/>
<path
android:pathData="m22.0479,14.0086q0,0.5257 -0.2079,0.9247 -0.2079,0.399 -0.595,0.6117 -0.3871,0.2103 -0.9032,0.2103 -0.7933,0 -1.2449,-0.466 -0.4492,-0.4683 -0.4492,-1.2808 0,-0.81 0.4492,-1.264 0.4492,-0.454 1.2497,-0.454 0.8005,0 1.2497,0.4588 0.4516,0.4588 0.4516,1.2592zM21.3287,14.0086q0,-0.5448 -0.2581,-0.853 -0.2581,-0.3106 -0.724,-0.3106 -0.4731,0 -0.7312,0.3082 -0.2581,0.3058 -0.2581,0.8554 0,0.5544 0.2628,0.8745 0.2652,0.3178 0.7216,0.3178 0.4731,0 0.7288,-0.3106 0.2581,-0.3106 0.2581,-0.8817z"
android:strokeWidth="0.0849532"
android:fillColor="#ff00ff"
android:strokeColor="#000000"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_bg" />
<foreground android:drawable="@drawable/ic_launcher_fg" />
</adaptive-icon>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_bg" />
<foreground android:drawable="@drawable/ic_launcher_fg" />
</adaptive-icon>
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions android-template/app/src/main/res/values-w820dp/dimens.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
5 changes: 5 additions & 0 deletions android-template/app/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
3 changes: 3 additions & 0 deletions android-template/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">WebviewAndroidJni</string>
</resources>
25 changes: 25 additions & 0 deletions android-template/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
18 changes: 18 additions & 0 deletions android-template/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.useAndroidX=true
2 changes: 2 additions & 0 deletions android-template/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
rootProject.name='AndroidWebviewJni'
include ':app'