Android: Crash in Shinobi-premium-1.7.1


#1

Error stack-trace noticed with latest Shinobi-premium-1.7.1 libraries.

E/ACRA    ( 7964): java.lang.NullPointerException

E/ACRA    ( 7964):      at com.shinobicontrols.charts.ad.a(SourceFile:99)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.ad.a(SourceFile:43)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.ad.a(SourceFile:152)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.ad.a(SourceFile:54)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.DateTimeAxis.a(SourceFile:503)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.dg.e(SourceFile:224)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.dg.d(SourceFile:161)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.dg.a(SourceFile:58)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.Axis.a(SourceFile:2453)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.w.a(SourceFile:311)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.s.onDraw(SourceFile:54)

E/ACRA    ( 7964):      at android.view.View.draw(View.java:14870)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.s.draw(SourceFile:64)

E/ACRA    ( 7964):      at android.view.View.draw(View.java:14751)

E/ACRA    ( 7964):      at android.view.ViewGroup.drawChild(ViewGroup.java:3316)

E/ACRA    ( 7964):      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3153)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.w.dispatchDraw(SourceFile:192)

E/ACRA    ( 7964):      at android.view.View.draw(View.java:14749)

E/ACRA    ( 7964):      at android.view.ViewGroup.drawChild(ViewGroup.java:3316)

E/ACRA    ( 7964):      at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3153)

E/ACRA    ( 7964):      at android.view.View.draw(View.java:14873)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.v.b(SourceFile:1708)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.v.a(SourceFile:31)

E/ACRA    ( 7964):      at com.shinobicontrols.charts.v$1.run(SourceFile:1695)

E/ACRA    ( 7964):      at android.os.Handler.handleCallback(Handler.java:730)

E/ACRA    ( 7964):      at android.os.Handler.dispatchMessage(Handler.java:92)

E/ACRA    ( 7964):      at android.os.Looper.loop(Looper.java:137)

E/ACRA    ( 7964):      at android.app.ActivityThread.main(ActivityThread.java:5493)

E/ACRA    ( 7964):      at java.lang.reflect.Method.invokeNative(Native Method)

E/ACRA    ( 7964):      at java.lang.reflect.Method.invoke(Method.java:525)

E/ACRA    ( 7964):      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)

E/ACRA    ( 7964):      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)

E/ACRA    ( 7964):      at dalvik.system.NativeStart.main(Native Method)

Following is the code snippet - 

  1. dateNumberDataAdapter typically has dataPoints included in sorted-order naturally from listOfInputeElements, based on the Date property.

  2. If dateNumberDataAdapter list of DataPoints are not in the same order as the Major-ticks of DateTimeAxis, at least, based on the Date property, would that be a problem?

    TimeZone timeZone = TimeZone.getTimeZone(“America/New_York”);
    SimpleDateFormat dateFormat = new SimpleDateFormat(“MMM dd, yyyy”);
    dateFormat.setTimeZone(timeZone);

         Data<Date, Number> dataPoint = null;
         DataAdapter<Date, Number> dateNumberDataAdapter = new SimpleDataAdapter<Date, Number>();
         for (Element data : listOfInputElements) {
             try {
                 Date date = dateFormat.parse(data.m_asOfDateTime);
                 dataPoint = new DataPoint<Date, Number>(date, data.m_totalMarketValue);
                 dateNumberDataAdapter.add(dataPoint);
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }
         }
    
         List<Date> xAxisLabels = new ArrayList<Date>();
    
         for (Data<Date, Number> data : dateNumberDataAdapter.getDataPointsForDisplay()) {
             xAxisLabels.add(data.getX());
         }
    
         Collections.sort(xAxisLabels);
    
         Date minXAxisDate = xAxisLabels.get(0);
         Date maxXAxisDate = xAxisLabels.get(xAxisLabels.size() - 1);
    
         TimeZone timeZone = TimeZone.getTimeZone("America/New_York");
         SimpleDateFormat labelDateFormat = new SimpleDateFormat("MMM");
    
         DateTimeAxis xAxis = new DateTimeAxis(new DateRange(minXAxisDate, maxXAxisDate));
         xAxis.setLabelFormat(labelDateFormat);
         xAxis.setTitle(title);
         xAxis.setMajorTickFrequency(new DateFrequency(2, DateFrequency.Denomination.MONTHS));
    
         /**
    

    Rest of the code-sample applies X-Axis styling and appearance, and ensures the x-Axis implementation of DateTimeAxis is included into the ShinobiChart, and the chart is forced-redrawn.
    **/


#2

Hi JVSSPraneeth,

Thanks for providing this information. Can you confirm that you get this bug even if you don’t set the label format and the major tick frequency for your X axis? In order for us to narrow down the cause of this issue it would really help if you could create a small sample app that reproduces this NullPointerException crash. If you could do this then can you send this, along with any other useful information, over to our support email at info@shinobicontrols.com

Thanks again,

Joel


#3

Thanks Joel,

  1. I did try your suggested alternative, to not set the label-format, and the major-tick frequency on the X-axis. However, the NullPointer with the same stack-trace as above persisted.

  2. I did try switching between the premium-1.7.1-1, and the trial-1.7.1-1 Shinobi Android Libraries. Apparently, both libraries failed with the same NullPointer, with the same stack-trace as above.

  3. I then created a sample application, replicated almost everything from our production android-app, into the sample-app program-code adequately for presenting a Shinobi-chart on the mobile device screen. I ensured the GLES Version declarations, and the Hardware-acceleration attributes were also replicated as-is from the production-app to the sample-app. I also tried switching between the premium and the trial Shinobi Android Libraries at the above mentioned version. Apparently, the NullPointer could never the reproduced in the sample-app.

  4. The only noticeable difference between the Production Android-app, and the Sample-app I had developed to replicate the NullPointer issue in the DateTimeAxis used for the X-axis on the chart is that apart from the Chart-container in the Production-app, we also have a “Legal-Disclaimer”, that has dynamically adjustable height and width bounds toward the bottom of the screen, below the Chart-container. The content displayed within this Legal-Disclaimer reusable component also is dynamic, and typically in a race-condition against the data that is used to prepare the chart. The sample-app did not have this dynamic “Legal-Disclaimer” re-usable component. Neither was the chart-data dynamic, and only parsed from a JSON asset-file in the sample-app.

  5. Unless, an unobfuscated stack-trace is generated from the above stack-trace by using retrace tool from proguard, or similar de-obfuscation tool, we may not be able to clearly understand if resizing the Chart-Container may have caused the crash-issue, since X-axis is the very first component amongst the sequence of invocations to add the chart-components into the Chart-container.


#4

Joel,

I removed the “Legal-Disclaimer” resuable view-component from below the Chart-container within our Production-app, and the NullPointer issue isn’t reproducible anymore.

com.shinobicontrols.charts.ChartView needs to adjust the ShinobiChart dynamically based off of other view-components sharing the device-screen.