FokkeZB / nl.fokkezb.loading

The widget provides a simple loading mask that can be easily styled and configured.
93 stars 18 forks source link

java.lang.NullPointerException #11

Closed mcvendrell closed 10 years ago

mcvendrell commented 10 years ago

Hi Fokke.

Since I updated from Ti 3.2.3GA to Ti 3.3.0GA, I begin to have problems with this widget. I suppose it has something to be with the new Titanium way of work with windows (all new activities, and default appcompat library that uses always the action bar), because now I see the loading windows as "overlapped window" over the current (before, I never see the "actionbar" when I called your widget).

This is the error I got when I load my app (it retrieves data from ACS and then hides the loading widget):

java.lang.NullPointerException
at ti.modules.titanium.ui.widget.TiUIActivityIndicator.setStyle(TiUIActivityIndicator.java:164)
at ti.modules.titanium.ui.widget.TiUIActivityIndicator.processProperties(TiUIActivityIndicator.java:86)
at org.appcelerator.kroll.KrollProxy.setModelListener(KrollProxy.java:1185)
at org.appcelerator.titanium.proxy.TiViewProxy.realizeViews(TiViewProxy.java:480)
at org.appcelerator.titanium.proxy.TiViewProxy.handleGetView(TiViewProxy.java:471)
at org.appcelerator.titanium.proxy.TiViewProxy.getOrCreateView(TiViewProxy.java:449)
at ti.modules.titanium.ui.ActivityIndicatorProxy.handleHide(ActivityIndicatorProxy.java:94)
at org.appcelerator.titanium.proxy.TiViewProxy.handleMessage(TiViewProxy.java:241)
at ti.modules.titanium.ui.ActivityIndicatorProxy.handleMessage(ActivityIndicatorProxy.java:67)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5039)
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:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)

The error happens when I make the Alloy.Globals.loading.hide()

If I don't use the widget, all works well. Any idea?

Similar problem, but for the default Titanium indicator here: https://developer.appcelerator.com/question/174850/javalangnullpointerexception-on-tiuiactivityindicatorsetstyletiuiactivityindicatorjava164

More info: it only happens when I use it in my first screen (when the app starts). If I use it in any other place, all works well.

Pd.- Thanks for this great widget

Brian-McBride commented 10 years ago

Seems I'm having the same issue. On Android calling the hide method crashes the entire app in 3.3.0.

FokkeZB commented 10 years ago

I cannot reproduce this on Genymotion with the newly added test app: https://github.com/FokkeZB/nl.fokkezb.loading/tree/test

Please make a reproducible test case.

mcvendrell commented 10 years ago

It's a little hard to explain, but I will try.

For me, this only happens on complex interfaces. My starting window is a TabGroup, and one tab gets the info from Node.ACS (messageList). Is in that moment when the widget crashes.

<Alloy>
    <TabGroup id="mainTab" class="container">
        <Tab id="alerts" title="L('alerts', 'Alerts')">
            <Require src="messageList" />
        </Tab>
        <Tab id="config" title="L('config', 'Config')">
            <Require src="config" />
        </Tab>
        <Tab id="info" title="L('info', 'Info')">
            <Require src="info" />
        </Tab>
    </TabGroup>
</Alloy>

The messageList only retrieves info from Node.ACS and put it in a table. At the start I call Alloy.Globals.loading.show(); and when the data is retrieved I call Alloy.Globals.loading.hide();

In the hide I get the error only if is the first call, in other words, when the app load the screen for the first time. To work around it, I put a flag for first call to don't use the widget call, but use it in the subsequent calls, what make things work perfect.

I also detected that loading new windows with calls to "retrieve data" after setting widget to show(), can crash the widget too on the hide() call.

Maybe the bug have relation with the parent window not being fully "available" when the widget is used (sometimes code is faster than the "visible" window to be executed).

You test case is so basic, so no problems will be found on it. Hope this info can help in some way.

FokkeZB commented 10 years ago

I think the problem is that if you create a new window (thus activity) on Android and the former hasn't finished starting (and displaying) yet, it will be cancelled so subsequent calls will give a null pointer exception.

For Android, I think it's better to use the built-in activity indicator dialogs instead. I think I'll refactor the widget to use these, but for now you could do this yourself by setting Alloy.Globals.loading to a custom object for Android only.

mcvendrell commented 10 years ago

In my current project I'm using the Android activity indicator for "conflictive windows" (like those I open and load info at the same time), and using your widget for operations in windows already opened (for example to reload data when user press reload button).

Thank you for your recommendations and for this wonderful widget.