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

Android Label widget can't be used on API 28 or earlier #1878

Closed
freakboy3742 opened this issue Apr 17, 2023 · 1 comment · Fixed by #1941
Closed

Android Label widget can't be used on API 28 or earlier #1878

freakboy3742 opened this issue Apr 17, 2023 · 1 comment · Fixed by #1941
Labels
android The issue relates to Android mobile support. bug A crash or error in behavior.

Comments

@freakboy3742
Copy link
Member

freakboy3742 commented Apr 17, 2023

Describe the bug

The Android Label widget references the LineBreaker class, which wasn't added until API level 29 (Android 10).

If you try to launch an app that uses label on Android 9 or earlier, the app will crash.

Steps to reproduce

  1. Launch any Android ap that uses toga.Label
  2. See error

(logs provided below)

Expected behavior

The gradle project specifies an API minimum of 21 (5); Toga should adhere to the same minimum.

Screenshots

No response

Environment

  • Operating System: Android 8.1
  • Python version: Any
  • Software versions:
    • Briefcase: 0.3.14
    • Toga: 0.3.1

Logs

04-17 15:29:56.737  6976  6976 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.keith_magee.traveltips/org.beeware.android.MainActivity}: com.chaquo.python.PyException: java.lang.NoClassDefFoundError: android.graphics.text.LineBreaker
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2805)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2883)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at android.app.ActivityThread.-wrap11(Unknown Source:0)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1613)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:106)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:164)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:6523)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:857)
04-17 15:29:56.737  6976  6976 E AndroidRuntime: Caused by: com.chaquo.python.PyException: java.lang.NoClassDefFoundError: android.graphics.text.LineBreaker
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at com.chaquo.python.PyObject.callAttr(PyObject.java:225)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at org.beeware.android.MainActivity.onCreate(MainActivity.java:85)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at android.app.Activity.performCreate(Activity.java:7023)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at android.app.Activity.performCreate(Activity.java:7014)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2758)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        ... 9 more
04-17 15:29:56.737  6976  6976 E AndroidRuntime: Caused by: java.lang.NoClassDefFoundError: android.graphics.text.LineBreaker
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at java.lang.Class.classForName(Native Method)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at java.lang.Class.forName(Class.java:453)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.java.chaquopy.CQPEnv.FindClass(env.pxi:63)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.java.chaquopy.JavaClass.__new__(class.pxi:79)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.java.chaquopy.new_class(class.pxi:67)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.java.chaquopy.jclass(class.pxi:59)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.java.chaquopy.jclass(class.pxi:53)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.java.chaquopy.jclass(class.pxi:34)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.toga_android.libs.android.graphics.<module>(graphics.py:17)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.java.chaquopy.import_override(import.pxi:26)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.toga_android.app.<module>(app.py:9)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.java.chaquopy.import_override(import.pxi:26)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.toga_android.factory.<module>(factory.py:2)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.importlib._bootstrap._call_with_frames_removed(<frozen importlib._bootstrap>:241)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.importlib._bootstrap_external.exec_module(<frozen importlib._bootstrap_external>:883)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.java.android.importer.exec_module(importer.py:554)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.java.android.importer.exec_module(importer.py:606)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.importlib._bootstrap._load_unlocked(<frozen importlib._bootstrap>:688)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.importlib._bootstrap._find_and_load_unlocked(<frozen importlib._bootstrap>:1006)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.importlib._bootstrap._find_and_load(<frozen importlib._bootstrap>:1027)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.importlib._bootstrap._gcd_import(<frozen importlib._bootstrap>:1050)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.importlib.import_module(__init__.py:126)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.toga.platform.get_platform_factory(platform.py:122)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.toga.app.__init__(app.py:323)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.traveltips.app.main(app.py:237)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.__main__.<module>(__main__.py:4)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.runpy._run_code(runpy.py:86)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.runpy._run_module_code(runpy.py:96)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.runpy.run_module(runpy.py:224)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.chaquopy_java.call(chaquopy_java.pyx:354)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at <python>.chaquopy_java.Java_com_chaquo_python_PyObject_callAttrThrowsNative(chaquopy_java.pyx:326)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at com.chaquo.python.PyObject.callAttrThrowsNative(Native Method)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at com.chaquo.python.PyObject.callAttrThrows(PyObject.java:232)
04-17 15:29:56.737  6976  6976 E AndroidRuntime:        at com.chaquo.python.PyObject.callAttr(PyObject.java:221)

Additional context

The implementation of rehint() for Label includes a version check against API Level O (26/8.0), to protect against the non-existence of setJustificationMode API; however, the constant that is used in both cases uses the LineBreaker class, which was only introduced in API 29.

The issue isn't just the usage of the constant - it's the import of the LineBreaker class, which won't exist (and thus crashes on app startup).

@freakboy3742 freakboy3742 added bug A crash or error in behavior. android The issue relates to Android mobile support. labels Apr 17, 2023
@mhsmith
Copy link
Member

mhsmith commented May 13, 2023

The app doesn't even need to use a Label, because the crash happens while importing toga_android.app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
android The issue relates to Android mobile support. bug A crash or error in behavior.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants