Android Question Crash with MsgboxAsync

Creideiki

Active Member
Licensed User
Longtime User
Hi there,

I try to convert the Msgboxes to MsgboxAsync. Since there are some MsgBoxes one after the other, I try to de-parallelize them with Wait For.
Now I got a crash:
[CODE title="Stack trace"]lizenzclass$ResumableSub_leseDateiresume (java line: 213)
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.ref.WeakReference.get()' on a null object reference
at anywheresoftware.b4a.keywords.Common.Msgbox2Async(Common.java:488)
at anywheresoftware.b4a.keywords.Common.MsgboxAsync(Common.java:466)
at de.xxx.yyy.lizenzclass$ResumableSub_leseDatei.resume(lizenzclass.java:213)
at de.xxx.yyy.lizenzclass._lesedatei(lizenzclass.java:125)
at de.xxx.yyy.main$ResumableSub_findeLizenz.resume(main.java:2797)
at de.xxx.yyy.main._findelizenz(main.java:2633)
at de.xxx.yyy.main$ResumableSub_pruefeLizenz.resume(main.java:3220)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:250)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:190)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)
at anywheresoftware.b4a.keywords.Common$1.onClick(Common.java:492)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:169)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6251)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.ref.WeakReference.get()' on a null object reference
[/CODE]

The code is quite complex.
The original call is in Main.Activity_Create. It calls a resumable sub (well, since I need Wait For, many subs have to be resumable) called pruefeLizenz. That one calls leseDatei in the Class LizenzClass. The instance of this class is declared in Main.Process_Globals and initialized in Starter.
In this sub, the App crashes while calling an simple MsgboxAsync.

I tried to create a litte App, which mimic the behaviour of the original app to show the crash; but this app works as expected.

I have no idea what could happen there. I am quite shure the logical flow is correct; I think it has something to do with the resumable sub / async thing and perhaps a problem with the right context.
Has anybody an idea what's going wrong?

Thank you.
 
Thanks for your Answer.
To use the Sender Filter I need an object to filter. Msgbox2Async returns an object, but MsgboxAsync doesn't. So I can't filter here.
 
Upvote 0
I rewrote the crashing part a bit.
I concentrated the Msgboxes of leseDatei in a sub named showLeseErgebnis with one MsgboxAsync. Same error.
I then replaced the MsgboxAsync by a Msgbox2Async and used the sender filter. Same error.
I then replaced the MsgboxAsync by a simple Msgbox and got the following crash:
[CODE lang="b4x" title="Stacktrace"]lizenzclass$ResumableSub_showLeseErgebnisresume (java line: 412)
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.view.ViewRootImpl.setView(ViewRootImpl.java:800)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:351)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.app.Dialog.show(Dialog.java:322)
at anywheresoftware.b4a.Msgbox.msgbox(Msgbox.java:169)
at anywheresoftware.b4a.keywords.Common.Msgbox2(Common.java:454)
at anywheresoftware.b4a.keywords.Common.Msgbox(Common.java:433)
at de.okabrechnungssysteme.HKZaehlerB4A.lizenzclass$ResumableSub_showLeseErgebnis.resume(lizenzclass.java:412)
at de.okabrechnungssysteme.HKZaehlerB4A.lizenzclass._showleseergebnis(lizenzclass.java:295)
at de.okabrechnungssysteme.HKZaehlerB4A.main$ResumableSub_findeLizenz.resume(main.java:2799)
at de.okabrechnungssysteme.HKZaehlerB4A.main._findelizenz(main.java:2633)
at de.okabrechnungssysteme.HKZaehlerB4A.main$ResumableSub_pruefeLizenz.resume(main.java:3222)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:250)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:190)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)
at anywheresoftware.b4a.keywords.Common$1.onClick(Common.java:492)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:169)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6251)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
[/CODE]
 
Upvote 0
Next try: I moved the sub to Main. That works.

I have to refactor the whole App to replace MsgBox with MsgboxAsync. When I have to move each and any MsgBox out of the Class modules, that will be an desaster. I know it's better to du UI in the Activities, but there are many places it would get very expensive to move any UI out of the Classes.

For clarity, here the excerpt of the relevant subs:
[CODE lang="b4x" title="Main"]Private Sub findeLizenz As ResumableSub
Dim fd As FileDialog
'[...]
If fd.Show("Lizenz-Datei suchen","OK","Abbruch","",Null) <> DialogResponse.POSITIVE Then
MsgboxAsync("Benutzerabbruch, kein Lizenz übernommen", "Lizenz")
Wait For MsgBox_Result (Result As Int)
Return False
End If
'[...]
Wait For (Lizenz.showLeseErgebnis(stat)) Complete (Result As Int)
Return stat = Lizenz.DATEISTATUS_OK
End Sub
[/CODE]
[CODE lang="b4x" title="Lizenz"]Public Sub showLeseErgebnis(status As Int) As ResumableSub
Dim txt As String
Select status
Case Lizenz.DATEISTATUS_OK: txt = "Lizenz wurde gespeichert."
Case Lizenz.DATEISTATUS_WRONGPROG: txt = "Die Lizenz-Datei gehört nicht zu " & sProgLizenzName
Case Lizenz.DATEISTATUS_NOCHECK: txt = "MAC Adresse und IMEI sind nicht verfügbar, Lizenz kann nicht geprüft werden!" & CRLF & _
"Das WLAN muss zur Prüfung eingeschaltet sein!"
Case Lizenz.DATEISTATUS_WRONGMAC: txt = "Die Lizenz-Datei gehört nicht zu diesem Gerät mit MAC: " & ALLG.GetDeviceMAC
Case Lizenz.DATEISTATUS_WRONGIMEI: txt = "Die Lizenz-Datei gehört nicht zu diesem Gerät mit IMEI: " & ALLG.GetDeviceId
Case Lizenz.DATEISTATUS_WRONGKEY: txt = "Der Lizenz-Key ist falsch, bitte an Support wenden."
Case Else: txt = "Interner Fehler: Status " & status
End Select
Dim sf As Object = Msgbox2Async(txt, "Lizenzprüfung", "OK", "", "", LoadBitmap(File.DirAssets, "btn_info.png"), False)
Wait For (sf) MsgBox_Result (Result As Int)
Return 0
End Sub
[/CODE]
 
Upvote 0
Upvote 0
Well... I think I hat a similar problem already... but I didn't remember... :(

I should've created the module as code module, not as class. But I thought it should be accessible from other parts, too... well, that's not necessary. So now it's created and initialized locally and anything works as a charm. ;)

Thanks to Erel and DonManfred.
 
Upvote 0
Code modules cannot handle events and therefore cannot have resumable subs.
Oh, ok... that's a showstopper indeed. I thought code modules would work as if the code was in the calling module... but since we have to replace the Msgboxes by the Async variants we have to use resumable subs.
The correct solution is to understand what causes this crash.
-> Object was initialized in Starter service instead of the Activity => solved ??
 
Upvote 0
Back
Top