You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Lifecycle rules remain native: Activities/ViewControllers are created by the OS. Python receives and controls them; it does not instantiate Android Activities directly.
51
51
- Small, growing surface: the shared Python API favors clarity and consistency, expanding progressively.
52
52
53
+
## Navigation model overview
54
+
55
+
- See the Navigation guide for full details and comparisons with other frameworks.
56
+
- iOS: one host `UIViewController` class, many instances pushed on a `UINavigationController`.
57
+
- Android: single host `Activity` with a `NavHostFragment` and a stack of generic `PageFragment`s driven by a navigation graph.
Copy file name to clipboardExpand all lines: docs/guides/navigation.md
+42-2Lines changed: 42 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -47,9 +47,49 @@ PythonNative forwards lifecycle events from the host:
47
47
-`on_save_instance_state`
48
48
-`on_restore_instance_state`
49
49
50
-
Android forwards Activity lifecycle via the template `MainActivity` and `PageActivity`. iOS forwards `viewWillAppear`/`viewWillDisappear` via an internal registry.
50
+
Android uses a single `MainActivity` hosting a `NavHostFragment` and a generic `PageFragment` per page. iOS forwards `viewWillAppear`/`viewWillDisappear` via an internal registry.
51
51
52
52
## Notes
53
53
54
-
- On Android, `push`launches a template `PageActivity` and passes `PY_PAGE_PATH` and optional JSON args.
54
+
- On Android, `push`navigates via `NavController` to a `PageFragment` and passes `page_path` and optional JSON `args`.
55
55
- On iOS, `push` uses the root `UINavigationController` to push a new `ViewController` and passes page info via KVC.
56
+
57
+
## Platform specifics
58
+
59
+
### iOS (UIViewController per page)
60
+
- Each PythonNative page is hosted by a Swift `ViewController` instance.
61
+
- Pages are pushed and popped on a root `UINavigationController`.
62
+
- Lifecycle is forwarded from Swift to the registered Python page instance.
63
+
- Root view wiring: `Page.set_root_view` sizes and inserts the Python-native view into the controller’s view.
64
+
65
+
Why this matches iOS conventions
66
+
- iOS apps commonly model screens as `UIViewController`s and use `UINavigationController` for hierarchical navigation.
67
+
- The approach integrates cleanly with add-to-app and system behaviors (e.g., state restoration).
68
+
69
+
### Android (single Activity, Fragment stack)
70
+
- Single host `MainActivity` sets a `NavHostFragment` containing a navigation graph.
71
+
- Each PythonNative page is represented by a generic `PageFragment` which instantiates the Python page and attaches its root view.
72
+
-`push`/`pop` delegate to `NavController` (via a small `Navigator` helper).
73
+
- Arguments (`page_path`, `args_json`) live in Fragment arguments and restore across configuration changes and process death.
74
+
75
+
Why this matches Android conventions
76
+
- Modern Android apps favor one Activity with many Fragments, using Jetpack Navigation for back stack, transitions, and deep links.
77
+
- It simplifies lifecycle, back handling, and state compared to one-Activity-per-screen.
78
+
79
+
## Comparison to other frameworks
80
+
- React Native
81
+
- Android: single `Activity`, screens managed via `Fragment`s (e.g., `react-native-screens`).
82
+
- iOS: screens map to `UIViewController`s pushed on `UINavigationController`.
83
+
- .NET MAUI / Xamarin.Forms
84
+
- Android: single `Activity`, pages via Fragments/Navigation.
85
+
- iOS: pages map to `UIViewController`s on a `UINavigationController`.
86
+
- NativeScript
87
+
- Android: single `Activity`, pages as `Fragment`s.
88
+
- iOS: pages as `UIViewController`s on `UINavigationController`.
89
+
- Flutter (special case)
90
+
- Android: single `Activity` (`FlutterActivity`/`FlutterFragmentActivity`).
Copy file name to clipboardExpand all lines: src/pythonnative/templates/android_template/app/src/main/java/com/pythonnative/android_template/MainActivity.kt
+7-58Lines changed: 7 additions & 58 deletions
Original file line number
Diff line number
Diff line change
@@ -5,12 +5,10 @@ import android.os.Bundle
5
5
importandroid.util.Log
6
6
importandroid.widget.TextView
7
7
importcom.chaquo.python.Python
8
-
importcom.chaquo.python.PyObject
9
8
importcom.chaquo.python.android.AndroidPlatform
10
9
11
10
classMainActivity : AppCompatActivity() {
12
11
privatevalTAG= javaClass.simpleName
13
-
privatevar page:PyObject?=null
14
12
15
13
overridefunonCreate(savedInstanceState:Bundle?) {
16
14
super.onCreate(savedInstanceState)
@@ -21,66 +19,17 @@ class MainActivity : AppCompatActivity() {
21
19
Python.start(AndroidPlatform(this))
22
20
}
23
21
try {
22
+
// Set content view to the NavHost layout; the initial page loads via nav_graph startDestination
23
+
setContentView(R.layout.activity_main)
24
+
// Optionally, bootstrap Python so first fragment can create the initial page onCreate
24
25
val py =Python.getInstance()
25
-
// Instantiate MainPage directly and call on_create
26
-
val module = py.getModule("app.main_page")
27
-
val pageClass = module.get("MainPage")
28
-
page = pageClass?.call(this)
29
-
page?.callAttr("on_create")
26
+
// Touch module to ensure bundled Python code is available; actual instantiation happens in PageFragment
0 commit comments