mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-28 07:00:19 +00:00
feat: allow android apps with any name, fix android + windows for aarch64 target (#3213)
* use llvm objcopy to rename syms * use handlebars * it works! * remove linker code * better docs internally about dev.dioxus.main * use bundle identifier * double check bundle identifier is proper
This commit is contained in:
parent
1370bce182
commit
8a2922c663
13 changed files with 173 additions and 79 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -3,6 +3,9 @@
|
||||||
"[toml]": {
|
"[toml]": {
|
||||||
"editor.formatOnSave": false
|
"editor.formatOnSave": false
|
||||||
},
|
},
|
||||||
|
"[handlebars]": {
|
||||||
|
"editor.formatOnSave": false
|
||||||
|
},
|
||||||
// "rust-analyzer.check.workspace": true,
|
// "rust-analyzer.check.workspace": true,
|
||||||
// "rust-analyzer.check.workspace": false,
|
// "rust-analyzer.check.workspace": false,
|
||||||
// "rust-analyzer.check.features": "all",
|
// "rust-analyzer.check.features": "all",
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
package com.example.androidfinal
|
|
||||||
|
|
||||||
class MainActivity : WryActivity()
|
|
8
packages/cli/assets/android/MainActivity.kt.hbs
Normal file
8
packages/cli/assets/android/MainActivity.kt.hbs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
package dev.dioxus.main;
|
||||||
|
|
||||||
|
// need to re-export buildconfig down from the parent
|
||||||
|
import {{application_id}}.BuildConfig;
|
||||||
|
typealias BuildConfig = BuildConfig;
|
||||||
|
|
||||||
|
|
||||||
|
class MainActivity : WryActivity()
|
|
@ -4,10 +4,10 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace="com.example.androidfinal"
|
namespace="{{ application_id }}"
|
||||||
compileSdk = 33
|
compileSdk = 33
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "com.example.androidfinal"
|
applicationId = "{{ application_id }}"
|
||||||
minSdk = 24
|
minSdk = 24
|
||||||
targetSdk = 33
|
targetSdk = 33
|
||||||
versionCode = 1
|
versionCode = 1
|
|
@ -5,8 +5,8 @@
|
||||||
<application android:hasCode="true" android:supportsRtl="true" android:icon="@mipmap/ic_launcher"
|
<application android:hasCode="true" android:supportsRtl="true" android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name" android:theme="@style/AppTheme">
|
android:label="@string/app_name" android:theme="@style/AppTheme">
|
||||||
<activity android:configChanges="orientation|keyboardHidden" android:exported="true"
|
<activity android:configChanges="orientation|keyboardHidden" android:exported="true"
|
||||||
android:label="@string/app_name" android:name="com.example.androidfinal.MainActivity">
|
android:label="@string/app_name" android:name="dev.dioxus.main.MainActivity">
|
||||||
<meta-data android:name="android.app.lib_name" android:value="androidfinal" />
|
<meta-data android:name="android.app.lib_name" android:value="dioxusmain" />
|
||||||
<meta-data android:name="android.app.func_name" android:value="ANativeActivity_onCreate" />
|
<meta-data android:name="android.app.func_name" android:value="ANativeActivity_onCreate" />
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
|
@ -1,3 +0,0 @@
|
||||||
<resources>
|
|
||||||
<string name="app_name">Androidfinal</string>
|
|
||||||
</resources>
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">{{app_name}}</string>
|
||||||
|
</resources>
|
|
@ -347,9 +347,8 @@ impl AppBundle {
|
||||||
//
|
//
|
||||||
// todo(jon): maybe just symlink this rather than copy it?
|
// todo(jon): maybe just symlink this rather than copy it?
|
||||||
Platform::Android => {
|
Platform::Android => {
|
||||||
// https://github.com/rust-mobile/xbuild/blob/master/xbuild/template/lib.rs
|
self.copy_android_exe(&self.app.exe, &self.main_exe())
|
||||||
// https://github.com/rust-mobile/xbuild/blob/master/apk/src/lib.rs#L19
|
.await?;
|
||||||
std::fs::copy(&self.app.exe, self.main_exe())?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are all super simple, just copy the exe into the folder
|
// These are all super simple, just copy the exe into the folder
|
||||||
|
@ -703,10 +702,6 @@ impl AppBundle {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn bundle_identifier(&self) -> String {
|
|
||||||
format!("com.dioxuslabs.{}", self.build.krate.executable_name())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn macos_plist_contents(&self) -> Result<String> {
|
fn macos_plist_contents(&self) -> Result<String> {
|
||||||
handlebars::Handlebars::new()
|
handlebars::Handlebars::new()
|
||||||
.render_template(
|
.render_template(
|
||||||
|
@ -715,7 +710,7 @@ impl AppBundle {
|
||||||
display_name: self.build.platform_exe_name(),
|
display_name: self.build.platform_exe_name(),
|
||||||
bundle_name: self.build.platform_exe_name(),
|
bundle_name: self.build.platform_exe_name(),
|
||||||
executable_name: self.build.platform_exe_name(),
|
executable_name: self.build.platform_exe_name(),
|
||||||
bundle_identifier: format!("com.dioxuslabs.{}", self.build.platform_exe_name()),
|
bundle_identifier: self.build.krate.bundle_identifier(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.map_err(|e| e.into())
|
.map_err(|e| e.into())
|
||||||
|
@ -729,7 +724,7 @@ impl AppBundle {
|
||||||
display_name: self.build.platform_exe_name(),
|
display_name: self.build.platform_exe_name(),
|
||||||
bundle_name: self.build.platform_exe_name(),
|
bundle_name: self.build.platform_exe_name(),
|
||||||
executable_name: self.build.platform_exe_name(),
|
executable_name: self.build.platform_exe_name(),
|
||||||
bundle_identifier: format!("com.dioxuslabs.{}", self.build.platform_exe_name()),
|
bundle_identifier: self.build.krate.bundle_identifier(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.map_err(|e| e.into())
|
.map_err(|e| e.into())
|
||||||
|
@ -774,4 +769,15 @@ impl AppBundle {
|
||||||
.join("debug")
|
.join("debug")
|
||||||
.join("app-debug.apk")
|
.join("app-debug.apk")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Copy the Android executable to the target directory, and rename the hardcoded com_hardcoded_dioxuslabs entries
|
||||||
|
/// to the user's app name.
|
||||||
|
async fn copy_android_exe(&self, source: &Path, destination: &Path) -> Result<()> {
|
||||||
|
// we might want to eventually use the objcopy logic to handle this
|
||||||
|
//
|
||||||
|
// https://github.com/rust-mobile/xbuild/blob/master/xbuild/template/lib.rs
|
||||||
|
// https://github.com/rust-mobile/xbuild/blob/master/apk/src/lib.rs#L19
|
||||||
|
std::fs::copy(source, destination)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,6 +307,7 @@ impl BuildRequest {
|
||||||
pub(crate) fn android_rust_flags(&self) -> String {
|
pub(crate) fn android_rust_flags(&self) -> String {
|
||||||
let mut rust_flags = std::env::var("RUSTFLAGS").unwrap_or_default();
|
let mut rust_flags = std::env::var("RUSTFLAGS").unwrap_or_default();
|
||||||
|
|
||||||
|
// todo(jon): maybe we can make the symbol aliasing logic here instead of using llvm-objcopy
|
||||||
if self.build.platform() == Platform::Android {
|
if self.build.platform() == Platform::Android {
|
||||||
let cur_exe = std::env::current_exe().unwrap();
|
let cur_exe = std::env::current_exe().unwrap();
|
||||||
rust_flags.push_str(format!(" -Clinker={}", cur_exe.display()).as_str());
|
rust_flags.push_str(format!(" -Clinker={}", cur_exe.display()).as_str());
|
||||||
|
@ -456,19 +457,13 @@ impl BuildRequest {
|
||||||
let mut env_vars = vec![];
|
let mut env_vars = vec![];
|
||||||
|
|
||||||
if self.build.platform() == Platform::Android {
|
if self.build.platform() == Platform::Android {
|
||||||
let app = self.root_dir().join("app");
|
env_vars.push(("WRY_ANDROID_PACKAGE", "dev.dioxus.main".to_string()));
|
||||||
let app_main = app.join("src").join("main");
|
env_vars.push(("WRY_ANDROID_LIBRARY", "dioxusmain".to_string()));
|
||||||
let app_kotlin = app_main.join("kotlin");
|
|
||||||
let app_kotlin_out = app_kotlin.join("com").join("example").join("androidfinal");
|
|
||||||
|
|
||||||
env_vars.push((
|
|
||||||
"WRY_ANDROID_PACKAGE",
|
|
||||||
"com.example.androidfinal".to_string(),
|
|
||||||
));
|
|
||||||
env_vars.push(("WRY_ANDROID_LIBRARY", "androidfinal".to_string()));
|
|
||||||
env_vars.push((
|
env_vars.push((
|
||||||
"WRY_ANDROID_KOTLIN_FILES_OUT_DIR",
|
"WRY_ANDROID_KOTLIN_FILES_OUT_DIR",
|
||||||
app_kotlin_out.display().to_string(),
|
self.wry_android_kotlin_files_out_dir()
|
||||||
|
.display()
|
||||||
|
.to_string(),
|
||||||
));
|
));
|
||||||
|
|
||||||
env_vars.push(("RUSTFLAGS", self.android_rust_flags()))
|
env_vars.push(("RUSTFLAGS", self.android_rust_flags()))
|
||||||
|
@ -619,8 +614,10 @@ impl BuildRequest {
|
||||||
Platform::Liveview => self.krate.executable_name().to_string(),
|
Platform::Liveview => self.krate.executable_name().to_string(),
|
||||||
Platform::Windows => format!("{}.exe", self.krate.executable_name()),
|
Platform::Windows => format!("{}.exe", self.krate.executable_name()),
|
||||||
|
|
||||||
// from the apk spec, the root exe will actually be a shared library
|
// from the apk spec, the root exe is a shared library
|
||||||
Platform::Android => format!("lib{}.so", self.krate.executable_name()),
|
// we include the user's rust code as a shared library with a fixed namespacea
|
||||||
|
Platform::Android => "libdioxusmain.so".to_string(),
|
||||||
|
|
||||||
Platform::Web => unimplemented!("there's no main exe on web"), // this will be wrong, I think, but not important?
|
Platform::Web => unimplemented!("there's no main exe on web"), // this will be wrong, I think, but not important?
|
||||||
|
|
||||||
// todo: maybe this should be called AppRun?
|
// todo: maybe this should be called AppRun?
|
||||||
|
@ -643,7 +640,7 @@ impl BuildRequest {
|
||||||
let app_kotlin = app_main.join("kotlin");
|
let app_kotlin = app_main.join("kotlin");
|
||||||
let app_jnilibs = app_main.join("jniLibs");
|
let app_jnilibs = app_main.join("jniLibs");
|
||||||
let app_assets = app_main.join("assets");
|
let app_assets = app_main.join("assets");
|
||||||
let app_kotlin_out = app_kotlin.join("com").join("example").join("androidfinal");
|
let app_kotlin_out = self.wry_android_kotlin_files_out_dir();
|
||||||
create_dir_all(&app)?;
|
create_dir_all(&app)?;
|
||||||
create_dir_all(&app_main)?;
|
create_dir_all(&app_main)?;
|
||||||
create_dir_all(&app_kotlin)?;
|
create_dir_all(&app_kotlin)?;
|
||||||
|
@ -657,6 +654,18 @@ impl BuildRequest {
|
||||||
tracing::debug!("Initialized app/src/assets: {:?}", app_assets);
|
tracing::debug!("Initialized app/src/assets: {:?}", app_assets);
|
||||||
tracing::debug!("Initialized app/src/kotlin/main: {:?}", app_kotlin_out);
|
tracing::debug!("Initialized app/src/kotlin/main: {:?}", app_kotlin_out);
|
||||||
|
|
||||||
|
// handlerbars
|
||||||
|
let hbs = handlebars::Handlebars::new();
|
||||||
|
#[derive(serde::Serialize)]
|
||||||
|
struct HbsTypes {
|
||||||
|
application_id: String,
|
||||||
|
app_name: String,
|
||||||
|
}
|
||||||
|
let hbs_data = HbsTypes {
|
||||||
|
application_id: self.krate.full_mobile_app_name(),
|
||||||
|
app_name: self.krate.mobile_app_name(),
|
||||||
|
};
|
||||||
|
|
||||||
// Top-level gradle config
|
// Top-level gradle config
|
||||||
write(
|
write(
|
||||||
root.join("build.gradle.kts"),
|
root.join("build.gradle.kts"),
|
||||||
|
@ -692,7 +701,10 @@ impl BuildRequest {
|
||||||
// Now the app directory
|
// Now the app directory
|
||||||
write(
|
write(
|
||||||
app.join("build.gradle.kts"),
|
app.join("build.gradle.kts"),
|
||||||
include_bytes!("../../assets/android/gen/app/build.gradle.kts"),
|
hbs.render_template(
|
||||||
|
include_str!("../../assets/android/gen/app/build.gradle.kts.hbs"),
|
||||||
|
&hbs_data,
|
||||||
|
)?,
|
||||||
)?;
|
)?;
|
||||||
write(
|
write(
|
||||||
app.join("proguard-rules.pro"),
|
app.join("proguard-rules.pro"),
|
||||||
|
@ -700,18 +712,20 @@ impl BuildRequest {
|
||||||
)?;
|
)?;
|
||||||
write(
|
write(
|
||||||
app.join("src").join("main").join("AndroidManifest.xml"),
|
app.join("src").join("main").join("AndroidManifest.xml"),
|
||||||
include_bytes!("../../assets/android/gen/app/src/main/AndroidManifest.xml"),
|
hbs.render_template(
|
||||||
|
include_str!("../../assets/android/gen/app/src/main/AndroidManifest.xml.hbs"),
|
||||||
|
&hbs_data,
|
||||||
|
)?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Write the main activity manually since tao dropped support for it
|
// Write the main activity manually since tao dropped support for it
|
||||||
write(
|
write(
|
||||||
app_main
|
self.wry_android_kotlin_files_out_dir()
|
||||||
.join("kotlin")
|
|
||||||
.join("com")
|
|
||||||
.join("example")
|
|
||||||
.join("androidfinal")
|
|
||||||
.join("MainActivity.kt"),
|
.join("MainActivity.kt"),
|
||||||
include_bytes!("../../assets/android/MainActivity.kt"),
|
hbs.render_template(
|
||||||
|
include_str!("../../assets/android/MainActivity.kt.hbs"),
|
||||||
|
&hbs_data,
|
||||||
|
)?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Write the res folder
|
// Write the res folder
|
||||||
|
@ -720,7 +734,10 @@ impl BuildRequest {
|
||||||
create_dir_all(res.join("values"))?;
|
create_dir_all(res.join("values"))?;
|
||||||
write(
|
write(
|
||||||
res.join("values").join("strings.xml"),
|
res.join("values").join("strings.xml"),
|
||||||
include_bytes!("../../assets/android/gen/app/src/main/res/values/strings.xml"),
|
hbs.render_template(
|
||||||
|
include_str!("../../assets/android/gen/app/src/main/res/values/strings.xml.hbs"),
|
||||||
|
&hbs_data,
|
||||||
|
)?,
|
||||||
)?;
|
)?;
|
||||||
write(
|
write(
|
||||||
res.join("values").join("colors.xml"),
|
res.join("values").join("colors.xml"),
|
||||||
|
@ -790,4 +807,21 @@ impl BuildRequest {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn wry_android_kotlin_files_out_dir(&self) -> PathBuf {
|
||||||
|
let mut kotlin_dir = self
|
||||||
|
.root_dir()
|
||||||
|
.join("app")
|
||||||
|
.join("src")
|
||||||
|
.join("main")
|
||||||
|
.join("kotlin");
|
||||||
|
|
||||||
|
for segment in "dev.dioxus.main".split('.') {
|
||||||
|
kotlin_dir = kotlin_dir.join(segment);
|
||||||
|
}
|
||||||
|
|
||||||
|
tracing::debug!("app_kotlin_out: {:?}", kotlin_dir);
|
||||||
|
|
||||||
|
kotlin_dir
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -606,23 +606,54 @@ impl DioxusCrate {
|
||||||
return toolchain_dir
|
return toolchain_dir
|
||||||
.join("darwin-x86_64")
|
.join("darwin-x86_64")
|
||||||
.join("bin")
|
.join("bin")
|
||||||
.join("clang");
|
.join("aarch64-linux-android24-clang");
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg!(target_os = "linux") {
|
if cfg!(target_os = "linux") {
|
||||||
return toolchain_dir.join("linux-x86_64").join("bin").join("clang");
|
return toolchain_dir
|
||||||
|
.join("linux-x86_64")
|
||||||
|
.join("bin")
|
||||||
|
.join("aarch64-linux-android24-clang");
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg!(target_os = "windows") {
|
if cfg!(target_os = "windows") {
|
||||||
return toolchain_dir
|
return toolchain_dir
|
||||||
.join("windows-x86_64")
|
.join("windows-x86_64")
|
||||||
.join("bin")
|
.join("bin")
|
||||||
.join("clang.exe");
|
.join("aarch64-linux-android24-clang.cmd");
|
||||||
}
|
}
|
||||||
|
|
||||||
unimplemented!("Unsupported target os for android toolchain auodetection")
|
unimplemented!("Unsupported target os for android toolchain auodetection")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn mobile_org(&self) -> String {
|
||||||
|
let identifier = self.bundle_identifier();
|
||||||
|
let mut split = identifier.splitn(3, '.');
|
||||||
|
let sub = split
|
||||||
|
.next()
|
||||||
|
.expect("Identifier to have at least 3 periods like `com.example.app`");
|
||||||
|
let tld = split
|
||||||
|
.next()
|
||||||
|
.expect("Identifier to have at least 3 periods like `com.example.app`");
|
||||||
|
format!("{}.{}", sub, tld)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn mobile_app_name(&self) -> String {
|
||||||
|
self.executable_name().to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn full_mobile_app_name(&self) -> String {
|
||||||
|
format!("{}.{}", self.mobile_org(), self.mobile_app_name())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn bundle_identifier(&self) -> String {
|
||||||
|
if let Some(identifier) = self.config.bundle.identifier.clone() {
|
||||||
|
return identifier.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
format!("com.example.{}", self.executable_name())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for DioxusCrate {
|
impl std::fmt::Debug for DioxusCrate {
|
||||||
|
|
|
@ -21,6 +21,8 @@ use tokio::{
|
||||||
/// We might want to bring in websockets here too, so we know the exact channels the app is using to
|
/// We might want to bring in websockets here too, so we know the exact channels the app is using to
|
||||||
/// communicate with the devserver. Currently that's a broadcast-type system, so this struct isn't super
|
/// communicate with the devserver. Currently that's a broadcast-type system, so this struct isn't super
|
||||||
/// duper useful.
|
/// duper useful.
|
||||||
|
///
|
||||||
|
/// todo: restructure this such that "open" is a running task instead of blocking the main thread
|
||||||
pub(crate) struct AppHandle {
|
pub(crate) struct AppHandle {
|
||||||
pub(crate) app: AppBundle,
|
pub(crate) app: AppBundle,
|
||||||
|
|
||||||
|
@ -266,7 +268,7 @@ impl AppHandle {
|
||||||
.arg("launch")
|
.arg("launch")
|
||||||
.arg("--console")
|
.arg("--console")
|
||||||
.arg("booted")
|
.arg("booted")
|
||||||
.arg(self.app.bundle_identifier())
|
.arg(self.app.build.krate.bundle_identifier())
|
||||||
.envs(ios_envs)
|
.envs(ios_envs)
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
|
@ -451,30 +453,41 @@ impl AppHandle {
|
||||||
unimplemented!("dioxus-cli doesn't support ios devices yet.")
|
unimplemented!("dioxus-cli doesn't support ios devices yet.")
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn open_android_sim(&self, envs: Vec<(&str, String)>) -> Result<()> {
|
async fn open_android_sim(&self, envs: Vec<(&'static str, String)>) -> Result<()> {
|
||||||
// Install
|
let apk_path = self.app.apk_path();
|
||||||
// adb install -r app-debug.apk
|
let full_mobile_app_name = self.app.build.krate.full_mobile_app_name();
|
||||||
let _output = Command::new("adb")
|
|
||||||
.arg("install")
|
|
||||||
.arg("-r")
|
|
||||||
.arg(self.app.apk_path())
|
|
||||||
.stderr(Stdio::piped())
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.output()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
// adb shell am start -n com.example.androidfinal/com.example.androidfinal.MainActivity
|
// Start backgrounded since .open() is called while in the arm of the top-level match
|
||||||
let _output = Command::new("adb")
|
tokio::task::spawn(async move {
|
||||||
.arg("shell")
|
// Install
|
||||||
.arg("am")
|
// adb install -r app-debug.apk
|
||||||
.arg("start")
|
let _output = Command::new("adb")
|
||||||
.arg("-n")
|
.arg("install")
|
||||||
.arg("com.example.androidfinal/com.example.androidfinal.MainActivity")
|
.arg("-r")
|
||||||
.envs(envs)
|
.arg(apk_path)
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.output()
|
.output()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
// eventually, use the user's MainAcitivty, not our MainAcitivty
|
||||||
|
// adb shell am start -n dev.dioxus.main/dev.dioxus.main.MainActivity
|
||||||
|
let activity_name = format!("{}/dev.dioxus.main.MainActivity", full_mobile_app_name,);
|
||||||
|
|
||||||
|
let _output = Command::new("adb")
|
||||||
|
.arg("shell")
|
||||||
|
.arg("am")
|
||||||
|
.arg("start")
|
||||||
|
.arg("-n")
|
||||||
|
.arg(activity_name)
|
||||||
|
.envs(envs)
|
||||||
|
.stderr(Stdio::piped())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.output()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Result::<()>::Ok(())
|
||||||
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,7 +275,7 @@ impl AppRunner {
|
||||||
.arg("simctl")
|
.arg("simctl")
|
||||||
.arg("get_app_container")
|
.arg("get_app_container")
|
||||||
.arg("booted")
|
.arg("booted")
|
||||||
.arg(runner.app.bundle_identifier())
|
.arg(runner.app.build.krate.bundle_identifier())
|
||||||
.output()
|
.output()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
|
|
@ -47,19 +47,21 @@ pub fn root() {
|
||||||
dioxus_desktop::launch::launch(app, vec![], Default::default());
|
dioxus_desktop::launch::launch(app, vec![], Default::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Expose the `Java_dev_dioxus_main_WryActivity_create` function to the JNI layer.
|
||||||
|
/// We hardcode these to have a single trampoline for host Java code to call into.
|
||||||
|
///
|
||||||
|
/// This saves us from having to plumb the top-level package name all the way down into
|
||||||
|
/// this file. This is better for modularity (ie just call dioxus' main to run the app) as
|
||||||
|
/// well as cache thrashing since this crate doesn't rely on external env vars.
|
||||||
|
///
|
||||||
|
/// The CLI is expecting to find `dev.dioxus.main` in the final library. If you find a need to
|
||||||
|
/// change this, you'll need to change the CLI as well.
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
pub extern "C" fn start_app() {
|
pub extern "C" fn start_app() {
|
||||||
tao::android_binding!(
|
tao::android_binding!(dev_dioxus, main, WryActivity, wry::android_setup, root, tao);
|
||||||
com_example,
|
wry::android_binding!(dev_dioxus, main, wry);
|
||||||
androidfinal,
|
|
||||||
WryActivity,
|
|
||||||
wry::android_setup,
|
|
||||||
root,
|
|
||||||
tao
|
|
||||||
);
|
|
||||||
wry::android_binding!(com_example, androidfinal, wry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call our `main` function to initialize the rust runtime and set the launch binding trampoline
|
/// Call our `main` function to initialize the rust runtime and set the launch binding trampoline
|
||||||
|
|
Loading…
Reference in a new issue