Android Question Weird ArchiverPlusZip and MsgboxAsync issue

JohnC

Expert
Licensed User
Longtime User
OK, I am using Informatix ArchivePlusZip library and I'm getting this weird error:

B4X:
ZipDone
main$ResumableSub_DebugFiles_Clickresume (java line: 557)
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    at android.os.Handler.<init>(Handler.java:200)
    at android.os.Handler.<init>(Handler.java:114)
    at android.app.Dialog.<init>(Dialog.java:113)
    at android.app.AlertDialog.<init>(AlertDialog.java:125)
    at android.app.AlertDialog$Builder.create(AlertDialog.java:968)
    at anywheresoftware.b4a.keywords.Common.createMsgboxAlertDialog(Common.java:520)
    at anywheresoftware.b4a.keywords.Common.Msgbox2Async(Common.java:487)
    at anywheresoftware.b4a.keywords.Common.MsgboxAsync(Common.java:466)
    at com.omnisoft.handwash.main$ResumableSub_DebugFiles_Click.resume(main.java:557)
    at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:250)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:190)
    at a.a.a.f.a.a(SourceFile:88)
    at a.a.a.f.a.c(SourceFile:155)
    at a.a.a.f.a.a(SourceFile:163)
    at a.a.a.h.a.a(SourceFile:227)
    at a.a.a.i.a.a(SourceFile:12381)
    at a.a.a.i.a$1.run(SourceFile:1101)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)
** Activity (main) Pause, UserClosed = true **

Here's my code, what am I doing wrong?

B4X:
Sub DebugFiles_Click
    Dim Zip As ArchiverPlusZip    '1.13

    'Below are the values of the input folder path and output file path
    'AddFolder = /data/data/com.company.appname/files/Events
    'Misc.GetSharedDirectory = /storage/emulated/0/Android/data/com.company.appname/files/shared

    Zip.ZipExecutionMode = Zip.ZIP_EXECMODE_ASYNCHRONOUS

    Zip.AddFolderToZip(File.DirInternal & "/Events", Misc.GetSharedDirectory & "/debugs.zip" ,"Zip")
    Wait For Zip_ZipResult(Result As Int, ErrorMsg As String)

   Log("ZipDone")
    If Result <> Zip.ZIP_RESULT_SUCCESS Then
        MsgboxAsync("There was an Error creating the Debug ZIP file, Please try again (" & ErrorMsg & ")","Zip Error")
    Else
        MsgboxAsync("Zip OK","ZIP")
    End If

End Sub

As you can see the error message is in the log AFTER the "ZipDone" log message line, which suggests the error happens AFTER the ZIP operation has completed.

But when I check the ZIP file, it did properly "create" the zip file and it did have the folder of "Events" in it, but it did NOT properly place any files in that folder.

But If I remove the two MsgBoxAsync lines from the sub, the ZIP file will be created correctly including the files being placed in the Events folder inside the ZIP.

So, another question I have is how can an error that seems to occur AFTER the ZIP operation is complete effect whats in the zip file? If I had to take a guess, it seems the "Wait For" event is triggering BEFORE the zip operation has actually completed and because this is a resumable sub (due to "Wait For" being in it) and events are not firing when they should, things are getting messed up.

You will notice that I am setting the Zip execution mode to Async mode because this was suggested by the lib maker because when I left it set to the default "Sync" mode, it would not work with the Wait For statement at all.
 
Last edited:

b4x-de

Active Member
Licensed User
Longtime User
Hi,
is it a Code Module or a Class you are calling Zip.AddFolderToZip from?
Thomas
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
An Activity module (and I don't think you can call MsgBox from a class or code mod).
 
Last edited:
Upvote 0

b4x-de

Active Member
Licensed User
Longtime User
I think you are facing two different problems here which might be independent from each other.

The first problem are the missing files. You might want to double check with constant string values just to make sure single files are added. After this you could add some wildcards matching the files and see if it still works. Small steps might be helpful...

The second problem is the exception that is cased after the Zip was completed. It seems there is a problem with the resume. Have you tried to Wait For the Message Box result?

Thomas
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
The first problem are the missing files. You might want to double check with constant string values just to make sure single files are added. After this you could add some wildcards matching the files and see if it still works. Small steps might be helpful...

As I mentioned, if I remove the two msgbox lines, the zip file is created properly and has the proper folder and files in it. So, it doesn't make sense the problem is due to me specifying wrong input params.

The second problem is the exception that is cased after the Zip was completed. It seems there is a problem with the resume. Have you tried to Wait For the Message Box result?

What do you mean by "Resume"?
 
Upvote 0

b4x-de

Active Member
Licensed User
Longtime User
I think you might try to Wait For the MsgBox_Reuslt of your Asyc Message Boxes. According to the exception in your Log there is a problem to continue the resumable sub.

Thomas
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
I changed the code to this:
B4X:
    Log("Result: " & Result & ", ErrorMsg: " & ErrorMsg)
    If Result <> Zip.ZIP_RESULT_SUCCESS Then
        MsgboxAsync("Bad","ZIP")
        Wait For Msgbox_Result(Result As Int)
    Else
        MsgboxAsync("Zip OK","ZIP")
        Wait For Msgbox_Result(Result As Int)
    End If

And still got the error:

B4X:
Result: 0, ErrorMsg: null
main$ResumableSub_DebugFiles_Clickresume (java line: 566)
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    at android.os.Handler.<init>(Handler.java:200)
    at android.os.Handler.<init>(Handler.java:114)
    at android.app.Dialog.<init>(Dialog.java:113)
    at android.app.AlertDialog.<init>(AlertDialog.java:125)
    at android.app.AlertDialog$Builder.create(AlertDialog.java:968)
    at anywheresoftware.b4a.keywords.Common.createMsgboxAlertDialog(Common.java:520)
    at anywheresoftware.b4a.keywords.Common.Msgbox2Async(Common.java:487)
    at anywheresoftware.b4a.keywords.Common.MsgboxAsync(Common.java:466)
    at com.omnisoft.handwash.main$ResumableSub_DebugFiles_Click.resume(main.java:566)
    at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:250)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:190)
    at a.a.a.f.a.a(SourceFile:88)
    at a.a.a.f.a.c(SourceFile:155)
    at a.a.a.f.a.a(SourceFile:163)
    at a.a.a.h.a.a(SourceFile:227)
    at a.a.a.i.a.a(SourceFile:12381)
    at a.a.a.i.a$1.run(SourceFile:1101)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
    at java.lang.Thread.run(Thread.java:818)
** Activity (main) Pause, UserClosed = true **
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
Did you solve this error?. I have the same problem
Yeah, if your code modifies the screen at all (ie. Displays a MsgBox), then you need to have that code in a separate sub outside of the ZIP sub (in sync mode), and outside the ZIP_Event sub (Async mode).
 
Upvote 0

lumbanico

Member
I've got it:

B4X:
Sub btnBackup_Click

   arcBackup.ZipExecutionMode = arcBackup.ZIP_EXECMODE_ASYNCHRONOUS
    arcBackup.ZipCompression = True
    arcBackup.ZipCompressionLevel = 1
    arcBackup.AddFileToZip(strOrigen, strDestino, "arcBackup")
    Wait For arcBackup_ZipResult(Result As Int, ErrorMsg As String)

    Select Case Result
        Case arcBackup.ZIP_RESULT_SUCCESS
            CallSubDelayed(Me, "fncBackup_Success")
        Case Else
            CallSubDelayed(Me, "fncBackup_Error")
    End Select
    
End sub

Sub fncBackup_Success
    
    Msgbox2Async("Backup done.", "", "Ok", "", "", null, False)
    Wait For Msgbox_Result (Result As Int)

End Sub

Sub fncBackup_Error
    
    Msgbox2Async("Backup do not done.", "Error", "Ok", "", "", null, False)
    Wait For Msgbox_Result (Result As Int)

End Sub

Thanks.
 
Upvote 0

lumbanico

Member
As I wrote, prefer not to use ZipResult at all. If you do use it then make it as simple as possible and don't catch it with Wait For. Bad things will happen as this event is raised on a background thread.

Then, how then can I get then result of AddFileToZip to run the next sub? Because 'Sub arcBackup_ZipResult(Result As Int, ErrorMsg As String)' gives me a error.

Thanks.
 
Upvote 0

ilan

Expert
Licensed User
Longtime User
Don't use Wait For for this. Add another sub and handle the ZipResult event there.


like this erel:

B4X:
Sub Button1_Click
    myzip.AddFilesToZip(noFolderList,path,"myzip")   
End Sub

Sub myzip_ZipResult(Result As Int, ErrorMsg As String)
    Select Result
        Case myzip.ZIP_RESULT_SUCCESS
            CallSubDelayed(Me,"msgzip")
        Case Else
            CallSubDelayed(Me,"msgziperror")   
    End Select
End Sub

Sub msgziperror
    MsgboxAsync("לא היה ניתן ליצור קובץ דחוס.","שגיאה")   
End Sub

Sub msgzip
    '...'
End Sub
 
Upvote 0
Top