This is an automated email from the ASF dual-hosted git repository. erisu pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/cordova-docs.git
The following commit(s) were added to refs/heads/master by this push: new 749f516289 doc(android): refactor embedding webview (#1426) 749f516289 is described below commit 749f516289b374b9709a90933f0fcf46274ccac7 Author: エリス <er...@users.noreply.github.com> AuthorDate: Mon Jul 14 11:30:07 2025 +0900 doc(android): refactor embedding webview (#1426) - Updated how to install the framework using mavenCentral (Groovy DSL & Kotlin DSL Examples) - Improved TestActivity example (Kotlin & Java Examples) - Includes theming requirements - Added a bonus section on how to use Jetpack Compose instead of using XML layouts --------- Co-authored-by: Martin Horvath <martin.horv...@primebird.com> Co-authored-by: Jan Piotrowski <piotrowski+git...@gmail.com> --- www/docs/en/dev/guide/platforms/android/webview.md | 263 ++++++++++++++------- 1 file changed, 182 insertions(+), 81 deletions(-) diff --git a/www/docs/en/dev/guide/platforms/android/webview.md b/www/docs/en/dev/guide/platforms/android/webview.md index de9e2998d1..dcee153b15 100644 --- a/www/docs/en/dev/guide/platforms/android/webview.md +++ b/www/docs/en/dev/guide/platforms/android/webview.md @@ -33,102 +33,203 @@ of embedding a WebView. Starting with Cordova 1.9, the Android platform relies on a `CordovaWebView` component, which builds on a legacy `CordovaActivity` component that pre-dates the 1.9 release. -1. To follow these instructions, make sure you have the latest Cordova - distribution. Download it from - [cordova.apache.org](https://cordova.apache.org) and unzip its - Android package. +1. Create a new or open an exisiting native application. -1. Navigate to the Android package's `/framework` directory and run - `ant jar`. It creates the Cordova `.jar` file, formed as - `/framework/cordova-x.x.x.jar`. +2. Add the Cordova-Android framework dependency to your app module's build configuration. -1. Copy the `.jar` file into the Android project's `/libs` directory. + If your build configuration uses Groovy DSL, update `app/build.gradle` with the following: -1. Add the following to the application's `/res/xml/main.xml` file, - with the `layout_height`, `layout_width` and `id` modified to suit - the application: + ```groovy + dependencies { + implementation 'org.apache.cordova:framework:14.0.1' + } + ``` - <org.apache.cordova.CordovaWebView - android:id="@+id/tutorialView" - android:layout_width="match_parent" - android:layout_height="match_parent" /> + If your build configuration uses Kotlin DSL, update `app/build.gradle.kts` with the following: -1. Modify the activity so that it implements the `CordovaInterface`. - It should implement the included methods. You may wish to copy - them from `/framework/src/org/apache/cordova/CordovaActivity.java`, - or else implement them on your own. The following code fragment - shows a basic application that relies on the interface. Note how - the referenced view id matches the `id` attribute specified in the - XML fragment shown above: - - public class CordovaViewTestActivity extends Activity implements CordovaInterface { - CordovaWebView cwv; - /* Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.main); - cwv = (CordovaWebView) findViewById(R.id.tutorialView); - Config.init(this); - cwv.loadUrl(Config.getStartUrl()); - } + ```kotlin + dependencies { + implementation("org.apache.cordova:framework:14.0.1") + } + ``` -1. If the application needs to use the camera, implement the - following: + After making any changes to your build configuration file, make sure to "**Sync Project with Gradle Files**" so it will checkout the framework. - @Override - public void setActivityResultCallback(CordovaPlugin plugin) { - this.activityResultCallback = plugin; + **Note:** Your build configuration may already includes a `dependencies` block, so simply add the `implementation` line within the existing block. + + **Note:** You can find a list of available versions of released Cordova-Android framework on [Sonatype Maven Central Repository](https://central.sonatype.com/artifact/org.apache.cordova/framework/versions) or any other mirror of the Maven Central Repository. + + 3. Modify the layout file of the activity that shall host the Cordova view e.g. + + ```xml + <?xml version="1.0" encoding="utf-8"?> + <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <org.apache.cordova.engine.SystemWebView + android:id="@+id/cordovaWebView" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + </LinearLayout> + ``` + + 4. Modify your activity to extend `CordovaActivity` and override the `onCreate`, `makeWebView` and `createViews` to use your defined layout: + + **Kotlin Example:** + + ```kotlin + package org.apache.cordova.testapp + + import android.os.Bundle + import android.view.View + import androidx.activity.enableEdgeToEdge + import org.apache.cordova.CordovaActivity + import org.apache.cordova.CordovaWebView + import org.apache.cordova.CordovaWebViewImpl + import org.apache.cordova.engine.SystemWebView + import org.apache.cordova.engine.SystemWebViewEngine + + class TestActivity : CordovaActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContentView(R.layout.activity_test) } - /** - * Launch an activity for which you would like a result when it finished. When this activity exits, - * your onActivityResult() method is called. - * - * @param command The command object - * @param intent The intent to start - * @param requestCode The request code that is passed to callback to identify the activity - */ - public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) { - this.activityResultCallback = command; - this.activityResultKeepRunning = this.keepRunning; - - // If multitasking turned on, then disable it for activities that return results - if (command != null) { - this.keepRunning = false; - } - // Start activity - super.startActivityForResult(intent, requestCode); + override fun makeWebView(): CordovaWebView { + val appView = findViewById<View>(R.id.cordovaWebView) as SystemWebView + return CordovaWebViewImpl(SystemWebViewEngine(appView)) } - @Override - /** - * Called when an activity you launched exits, giving you the requestCode you started it with, - * the resultCode it returned, and any additional data from it. - * - * @param requestCode The request code originally supplied to startActivityForResult(), - * allowing you to identify who this result came from. - * @param resultCode The integer result code returned by the child activity through its setResult(). - * @param data An Intent, which can return result data to the caller (various data can be attached to Intent "extras"). - */ - protected void onActivityResult(int requestCode, int resultCode, Intent intent) { - super.onActivityResult(requestCode, resultCode, intent); - CordovaPlugin callback = this.activityResultCallback; - if (callback != null) { - callback.onActivityResult(requestCode, resultCode, intent); - } + override fun createViews() { + // leave empty so the layout is used } + } + ``` + + **Java Example:** -1. Finally, remember to add the thread pool, otherwise plugins - have no threads on which to run: + ```java + package org.apache.cordova.testapp; + import android.os.Bundle; + import android.view.View; + import androidx.activity.enableEdgeToEdge; + import org.apache.cordova.CordovaActivity; + import org.apache.cordova.CordovaWebView; + import org.apache.cordova.CordovaWebViewImpl; + import org.apache.cordova.engine.SystemWebView; + import org.apache.cordova.engine.SystemWebViewEngine; + + public class TestActivity extends CordovaActivity { @Override - public ExecutorService getThreadPool() { - return threadPool; + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_test); // layout file for your activity + super.init(); + loadUrl(launchUrl); } -1. Copy the application's HTML and JavaScript files to the Android - project's `/assets/www` directory. + @Override + protected CordovaWebView makeWebView() { + SystemWebView appView = (SystemWebView) findViewById(R.id.cordovaWebView); // id for the SystemWebView in previous step + return new CordovaWebViewImpl(new SystemWebViewEngine(appView)); + } + + @Override + protected void createViews() { + // leave empty so the layout is used + } + } + ``` + +3. Setup up the theming for your activity to comply with Cordova. + + As Cordova-Android framework displays a SplashScreen, we will need to update the native app's `themes.xml` to include a SplashScreen theme and `postSplashScreenTheme` for our Cordova activity. + + **Note:** Since `CordovaActivity` extends `AppCompatActivity`, the `postSplashScreenTheme` that the activity will transition to must inherit from a `Theme.AppCompat.*` style. For example, you can use `Theme.AppCompat.DayNight.NoActionBar` or a custom theme based on it. + + Below is an example and the theme names can be changed to your perfered naming. + + ```xml + <?xml version="1.0" encoding="utf-8"?> + <resources xmlns:tools="http://schemas.android.com/tools"> + <!-- The theme that will be used for the activity that displays Cordova --> + <style name="Theme.MyCordovaAppSplashScreen" parent="Theme.SplashScreen.IconBackground"> + <item name="windowSplashScreenBackground">@color/black</item> + <item name="windowSplashScreenAnimatedIcon">@drawable/ic_launcher_foreground</item> + <item name="windowSplashScreenAnimationDuration">200</item> + <item name="postSplashScreenTheme">@style/Theme.MyCordovaApp</item> + </style> + + <!-- The Post SplashScreen Theme --> + <style name="Theme.MyCordovaApp" parent="Theme.AppCompat.DayNight.NoActionBar" /> + </resources> + ``` + Next, update the `android:theme` attribute for your Cordova `<activity>` to `@style/Theme.MyCordovaAppSplashScreen` . + +4. Copy your application's web assets (HTML, CSS, JavaScript) to the Android project's `<app-root-directory>/app/src/main/assets/www/` directory. + +5. Copy your `config.xml` file to your Android project's `<app-root-directory>/app/src/main/res/xml/` directory. + +## Bonus: Jetpack Compose + +If your native Android application uses Jetpack Compose instead of XML layouts, you can still integrate the Cordova WebView by writing your Activity like this: + +```kotlin +package org.apache.cordova.testapp + +import android.os.Bundle +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.viewinterop.AndroidView +import org.apache.cordova.testapp.ui.theme.TestAppTheme +import org.apache.cordova.CordovaActivity +import org.apache.cordova.CordovaWebView +import org.apache.cordova.CordovaWebViewImpl +import org.apache.cordova.engine.SystemWebView +import org.apache.cordova.engine.SystemWebViewEngine + +class TestActivity : CordovaActivity() { + private lateinit var cordovaWebView: CordovaWebView + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + + // Set up the Cordova WebView manually + val systemWebView = SystemWebView(this) + cordovaWebView = CordovaWebViewImpl(SystemWebViewEngine(systemWebView)) + + setContent { + // Make sure to change "TestAppTheme" with your app's custom Jetpack Compose theme function. + TestAppTheme { + CordovaWebViewContainer(systemWebView = systemWebView) + } + } -1. Copy the `config.xml` file from `/framework/res/xml` to the - project's `/res/xml` directory. + loadUrl(launchUrl) + } + + override fun makeWebView(): CordovaWebView { + return cordovaWebView + } + + override fun createViews() { + // leave empty so the layout is used + } +} + +@Composable +fun CordovaWebViewContainer(systemWebView: SystemWebView) { + AndroidView( + factory = { systemWebView }, + modifier = Modifier.fillMaxSize() + ) +} +``` --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cordova.apache.org For additional commands, e-mail: commits-h...@cordova.apache.org