Android Question View Event Triggering after parent activity paused

JohnC

Expert
Licensed User
Longtime User
This is a continuation of posts discussed here:

https://www.b4x.com/android/forum/t...bug-or-the-dynamicgrid-bug.70413/#post-447051

https://www.b4x.com/android/forum/threads/msdynamicgridview-library.49331/page-4#post-442503

I also just got the below error on line 344 (see log at end of this post) on the "End Sub" of the "Activity_Paused":
B4X:
341 Sub Activity_Pause (UserClosed As Boolean)
342
343
344 End Sub

Since all these errors seem to be related to an event being triggered AFTER it's hosting activity was paused, this latest error gave me an idea....

It seems that if you "hide" this grid, it will no longer invoke events. Since this grid did not have a .Visible property, I placed it on a panel and set it's default property to visible=false. I then added a button to the main activity that set it to True. After the app loaded, the code is designed to load in the grid from a database. But since the panel was not visible, none of the grid events triggered. And as soon as I clicked the button to make the panel visible, then all the grid events triggered.

So what I will now try to fix this issue is this:

B4X:
Sub Activity_Pause (UserClosed As Boolean)

    pnlFavs.Visible = False

End Sub

Sub Activity_Resume

    pnlFavs.Visible = True

End Sub

I'm hoping that this will stop the grid events from triggering when it's parent activity is paused, thus fixing these intermittent errors.

The Log:
B4X:
** Service (starter) Create **
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
InAppBill.Init Time: 10:41:23
Audio Source: 1
Pos: 0 ItemID: 0 ItemTag: 1
DA_GetContent: ItemTag=1, DA.GetCount=25
Pos: 0 ItemID: 0 ItemTag: 1
DA_GetContent: ItemTag=1, DA.GetCount=25
Pos: 1 ItemID: 1 ItemTag: 2
DA_GetContent: ItemTag=2, DA.GetCount=25
Pos: 2 ItemID: 2 ItemTag: 3
DA_GetContent: ItemTag=3, DA.GetCount=25
Pos: 3 ItemID: 3 ItemTag: 4
DA_GetContent: ItemTag=4, DA.GetCount=25
Pos: 4 ItemID: 4 ItemTag: 5
DA_GetContent: ItemTag=5, DA.GetCount=25
Pos: 5 ItemID: 5 ItemTag: 6
DA_GetContent: ItemTag=6, DA.GetCount=25
Pos: 6 ItemID: 6 ItemTag: 7
DA_GetContent: ItemTag=7, DA.GetCount=25
Pos: 7 ItemID: 7 ItemTag: 8
DA_GetContent: ItemTag=8, DA.GetCount=25
Pos: 8 ItemID: 8 ItemTag: 9
DA_GetContent: ItemTag=9, DA.GetCount=25
Pos: 9 ItemID: 9 ItemTag: 10
DA_GetContent: ItemTag=10, DA.GetCount=25
Pos: 10 ItemID: 10 ItemTag: 11
DA_GetContent: ItemTag=11, DA.GetCount=25
Pos: 11 ItemID: 11 ItemTag: 12
DA_GetContent: ItemTag=12, DA.GetCount=25
Pos: 12 ItemID: 12 ItemTag: 13
DA_GetContent: ItemTag=13, DA.GetCount=25
Pos: 13 ItemID: 13 ItemTag: 14
DA_GetContent: ItemTag=14, DA.GetCount=25
Pos: 14 ItemID: 14 ItemTag: 15
DA_GetContent: ItemTag=15, DA.GetCount=25
Pos: 15 ItemID: 15 ItemTag: 16
DA_GetContent: ItemTag=16, DA.GetCount=25
Pos: 16 ItemID: 16 ItemTag: 17
DA_GetContent: ItemTag=17, DA.GetCount=25
Pos: 17 ItemID: 17 ItemTag: 18
DA_GetContent: ItemTag=18, DA.GetCount=25
Pos: 18 ItemID: 18 ItemTag: 19
DA_GetContent: ItemTag=19, DA.GetCount=25
Pos: 19 ItemID: 19 ItemTag: 20
DA_GetContent: ItemTag=20, DA.GetCount=25
Billing service connected.
Checking for in-app billing 3 support.
In-app billing version 3 supported for com.omnisoft.voiceit
Subscriptions AVAILABLE.
** Activity (main) Resume **
InApp_BillingSupported Call: true, Setup successful. (response: 0:OK)
Time: 10:41:24
Starting async operation: refresh inventory
Querying owned items, item type: inapp
Package name: com.omnisoft.voiceit
Calling getPurchases with continuation token: null
Owned items response: 0
Continuation token: null
Querying SKU details.
queryPrices: nothing to do because there are no SKUs.
Querying owned items, item type: subs
Package name: com.omnisoft.voiceit
Calling getPurchases with continuation token: null
Owned items response: 0
Continuation token: null
Querying SKU details.
queryPrices: nothing to do because there are no SKUs.
Ending async operation: refresh inventory
InAppBill_OwnedProducts Call: true
Time: 10:41:24
(MyMap) {}
Pos: 20 ItemID: 20 ItemTag: 21
DA_GetContent: ItemTag=21, DA.GetCount=25
Pos: 21 ItemID: 21 ItemTag: 22
DA_GetContent: ItemTag=22, DA.GetCount=25
Pos: 22 ItemID: 22 ItemTag: 23
DA_GetContent: ItemTag=23, DA.GetCount=25
Pos: 23 ItemID: 23 ItemTag: 24
DA_GetContent: ItemTag=24, DA.GetCount=25
Pos: 24 ItemID: 24 ItemTag: 25
DA_GetContent: ItemTag=25, DA.GetCount=25
Pos: 4 ItemID: 4 ItemTag: 5
DA_GetContent: ItemTag=5, DA.GetCount=25
Pos: 5 ItemID: 5 ItemTag: 6
DA_GetContent: ItemTag=6, DA.GetCount=25
Pos: 6 ItemID: 6 ItemTag: 7
DA_GetContent: ItemTag=7, DA.GetCount=25
Pos: 7 ItemID: 7 ItemTag: 8
DA_GetContent: ItemTag=8, DA.GetCount=25
Pos: 0 ItemID: 0 ItemTag: 1
DA_GetContent: ItemTag=1, DA.GetCount=25
Pos: 1 ItemID: 1 ItemTag: 2
DA_GetContent: ItemTag=2, DA.GetCount=25
Pos: 2 ItemID: 2 ItemTag: 3
DA_GetContent: ItemTag=3, DA.GetCount=25
Pos: 3 ItemID: 3 ItemTag: 4
DA_GetContent: ItemTag=4, DA.GetCount=25
Pos: 20 ItemID: 20 ItemTag: 21
DA_GetContent: ItemTag=21, DA.GetCount=25
Pos: 21 ItemID: 21 ItemTag: 22
DA_GetContent: ItemTag=22, DA.GetCount=25
Pos: 22 ItemID: 22 ItemTag: 23
DA_GetContent: ItemTag=23, DA.GetCount=25
Pos: 23 ItemID: 23 ItemTag: 24
DA_GetContent: ItemTag=24, DA.GetCount=25
Pos: 24 ItemID: 24 ItemTag: 25
DA_GetContent: ItemTag=25, DA.GetCount=25
Pos: 4 ItemID: 4 ItemTag: 5
DA_GetContent: ItemTag=5, DA.GetCount=25
Pos: 5 ItemID: 5 ItemTag: 6
DA_GetContent: ItemTag=6, DA.GetCount=25
Pos: 6 ItemID: 6 ItemTag: 7
DA_GetContent: ItemTag=7, DA.GetCount=25
Pos: 7 ItemID: 7 ItemTag: 8
DA_GetContent: ItemTag=8, DA.GetCount=25
Pos: 0 ItemID: 0 ItemTag: 1
DA_GetContent: ItemTag=1, DA.GetCount=25
Pos: 1 ItemID: 1 ItemTag: 2
DA_GetContent: ItemTag=2, DA.GetCount=25
Pos: 2 ItemID: 2 ItemTag: 3
DA_GetContent: ItemTag=3, DA.GetCount=25
Pos: 3 ItemID: 3 ItemTag: 4
DA_GetContent: ItemTag=4, DA.GetCount=25
Pos: 20 ItemID: 20 ItemTag: 21
DA_GetContent: ItemTag=21, DA.GetCount=25
Pos: 21 ItemID: 21 ItemTag: 22
DA_GetContent: ItemTag=22, DA.GetCount=25
Pos: 22 ItemID: 22 ItemTag: 23
DA_GetContent: ItemTag=23, DA.GetCount=25
Pos: 23 ItemID: 23 ItemTag: 24
DA_GetContent: ItemTag=24, DA.GetCount=25
Pos: 24 ItemID: 24 ItemTag: 25
DA_GetContent: ItemTag=25, DA.GetCount=25
ActionBar_MenuItemClick event fired, id:1
** Activity (main) Pause, UserClosed = false **
** Activity (comment) Create, isFirst = true **
** Activity (comment) Resume **
AB_Menu
** Activity (comment) Pause, UserClosed = true **
Pos: 0 ItemID: 0 ItemTag: 1
DA_GetContent: ItemTag=1, DA.GetCount=25
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
ActionBar_MenuItemClick event fired, id:1
No wakelock.
** Activity (main) Pause, UserClosed = false **
** Activity (comment) Create, isFirst = false **
** Activity (comment) Resume **
AB_Menu
** Activity (comment) Pause, UserClosed = true **
** Activity (main) Resume **
Pos: 0 ItemID: 0 ItemTag: 1
DA_GetContent: ItemTag=1, DA.GetCount=25
** Activity (main) Pause, UserClosed = false **
Error occurred on line: 344 (Main)
java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.shell.Shell.runGoodChain(Shell.java:461)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:283)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:247)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:134)
    at com.maximussoft.gridviews.B4ADynamicGridAdapter.getView(B4ADynamicGridAdapter.java:66)
    at android.widget.AbsListView.obtainView(AbsListView.java:2597)
    at android.widget.GridView.onMeasure(GridView.java:1043)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewGroup.measureChild(ViewGroup.java:4892)
    at android.view.ViewGroup.measureChildren(ViewGroup.java:4869)
    at anywheresoftware.b4a.BALayout.onMeasure(BALayout.java:64)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4921)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
    at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4921)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4921)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4921)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4921)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2418)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2129)
    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1282)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1493)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1179)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4861)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
    at android.view.Choreographer.doCallbacks(Choreographer.java:562)
    at android.view.Choreographer.doFrame(Choreographer.java:532)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
    at android.os.Handler.handleCallback(Handler.java:725)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:5293)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
    at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
    at com.omnisoft.voiceit.main._da_getcontent(main.java:1626)
    ... 56 more
java.lang.NullPointerException
    at android.widget.AbsListView.obtainView(AbsListView.java:2599)
    at android.widget.GridView.onMeasure(GridView.java:1043)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewGroup.measureChild(ViewGroup.java:4892)
    at android.view.ViewGroup.measureChildren(ViewGroup.java:4869)
    at anywheresoftware.b4a.BALayout.onMeasure(BALayout.java:64)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4921)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
    at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4921)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4921)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4921)
    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410)
    at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
    at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4921)
    at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2418)
    at android.view.View.measure(View.java:16047)
    at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2129)
    at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1282)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1493)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1179)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4861)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
    at android.view.Choreographer.doCallbacks(Choreographer.java:562)
    at android.view.Choreographer.doFrame(Choreographer.java:532)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
    at android.os.Handler.handleCallback(Handler.java:725)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:5293)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
    at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
    at dalvik.system.NativeStart.main(Native Method)

UPDATE: So far so good!

UPDATE #2: Still no crashes!
 
Last edited:

JohnC

Expert
Licensed User
Longtime User
The errors seem to be caused when the grid invoked one of it's events while it's parent activity was paused - meaning the crash happened when one of the grid's events tried to execute AFTER the parent activity was paused.

So, by hiding the grid before the activity pauses, it (so far) seems to prevent these erroneous events of the grid from being triggered while the activity is paused. Then I re-display the grid when the activity resumes.

I'm thinking that all of this should already be taking place automatically. But the fact that one of the grid's events are being triggered AFTER it's parent activity is paused, required me to do this to prevent that from happening.
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
I don't know if it's the job of the grid view to make sure it doesn't invoke one of it's events if it's parent activity is paused, or if it's a bug in B4A or the OS that is allowing the grid view to invoke an event after it's parent activity is paused.
 
Upvote 0

JohnC

Expert
Licensed User
Longtime User
Well, that's the thing - if the grid view is suppose to check if it's parent activity is active before invoking one of it's events, then this certainly could be a bug with the grid.

But I would think such basic housekeeping would be the job of the OS so that the developer of the grid view wouldn't have to manually do such a common task/check. But, I don't know enough about the inner workings of Android.
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
I dont think its the job of the grid. After all, do you check this in for e.g. listview or other code to check everytime if the activity is paused? Once On_Paused is issued, no code from that activity can be executed (as far as I can tell, all childview contexts are halted).

However! See here: https://www.b4x.com/android/forum/threads/tip-about-ba-raiseeventfromdifferentthread.17388/
The grid loads stuff on a different thread to keep things smooth. Erel says some of these events are held in a queue and are processed BEFORE activity_resume! This means you cannot have loaded the grid data in advance.
I think the queue should be handled after Activity_Resume and this is a bug/wrong design in B4A event handling.

Btw, nice debugging, keep up the good work.

It might be a bug in the grid too, just speculating, I've never used it.
Dude...no.
 
Upvote 0

Guardian17

Active Member
Licensed User
Longtime User
May not be related, but if you are using timers, all timers must get disabled in Activity_Pause, otherwise they can fire when your app resumes but you haven't yet re-loaded the associated views for those timers.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I think the queue should be handled after Activity_Resume and this is a bug/wrong design in B4A event handling.
The activity exits the paused state at the end of Activity_Create. It is important that the queued events will be raised before Activity_Resume to allow the developer to react to any changes that happened because of these events.

I've never seen any issue with this design. I also don't see how it is related to this NullPointerException.
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
It is important that the queued events will be raised before Activity_Resume to allow the developer to react to any changes that happened because of these events.
The developer will react to the event, in the event sub itself. He wont react in Activity_Resume. Activity_Resume needs to be run first so that the state of the activity is reconstructed before any event can be raised.

I also don't see how it is related to this NullPointerException.
I'm guessing that in Activity_Pause the developer is unloading all the objects, and loading them back in Resume. Therefore if the event is raised before resume, there are missing objects that cause NPE. Just a guess though, I havent debugged it.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
The developer will react to the event, in the event sub itself. He wont react in Activity_Resume. Activity_Resume needs to be run first so that the state of the activity is reconstructed before any event can be raised.
It is not really worth arguing about it as changing the behavior will break existing code.
The main reason for it to run before Activity_Resume is that you have a clear point where you can check whether something has happened or not.

'm guessing that in Activity_Pause the developer is unloading all the objects, and loading them back in Resume.
In that case the developer code is incorrect. The layout should be created in Activity_Create, not Activity_Resume. There is no need to unload any objects in Activity_Pause. If the activity was destroyed then all the views will be destroyed with it and Activity_Create will be called when the activity is visible again.
 
Upvote 0
Top