Crashing Android showing Website

Hello,

We are experiencing app crashes when displaying a single website that updates with new content every ~15 seconds, loaded using AJAX/JavaScript.

Player Hardware: DSCS9X
Display: Samsung Signage Device 50" 4K
Android App Version: 4.0.4
Connection: WiFi 5 Mbps

I have made the website publicly accessible here:

https://ap32.job4you.de/welcome/northeim_welcome_test/stellenticker.php?id=541bd3666b31b5088ae952b457a03f478a28525c

I tried reviewing some logs, but couldn’t find a definitive reason why the Xibo app crashes. When I reduce the size of the images on the left side to 540px in height, the app only crashes after several hours. However, with the original image size of approximately 2000px in height, the app crashes within minutes.

Hi Malte, are you the administrator of the site and able to make changes?

Without logs or further information, I’d guess that Xibo is crashing because the JavaScript script with loadMainContent() is causing the browser to crash. This might be due to how the swapping of the current and next elements is implemented—if the objects still have strong references, the garbage collector won’t release them, causing the cache to keep growing. Observers and event listeners are not removed; instead, more are added during runtime.

If you want to leave the code as is, try disabling caching in the browser and see if that serves as a workaround.

Additionally, I wonder if it makes sense to load ~5MB of new images every 15 seconds, especially since these images are not web-optimized and have dimensions of around ~5000x3000 pixels, even though they are ultimately displayed in a much smaller size. There are many online providers offering free APIs that return optimized images, which you could then use as the source in your script.

Replace current.remove() with current.detach().remove() to ensure that not only the current element is removed but also all associated observers. You could also use a temporary object to hold the new data—such as current, next, newNext—to avoid strong references to the “deleted” elements.

The code should look something like this (untested)
<!DOCTYPE html>
<html lang="de">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Stellenanzeige</title>
  <style>
    section {
      position: absolute;
      width: 100%;
      height: 100%;
      transition: transform 1s ease-in-out;
    }
    #current {
      transform: translateX(0);
    }
    #next {
      transform: translateX(100%);
    }
  </style>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
  <main>
    <section id="current"></section>
    <section id="next"></section>
  </main>

  <script>
    $(document).ready(function() {

      const CONTENT_URL = 'stellenticker.php';
      const CONTENT_ID = '541bd3666b31b5088ae952b457a03f478a28525c';
      const ANIMATION_DURATION = 5000; // Millisekunden
      const INTERVAL_DURATION = 15000; // Millisekunden

      // Lädt den Hauptinhalt
      function loadMainContent() {
        $.ajax({
          method: "POST",
          url: CONTENT_URL,
          dataType: "JSON",
          data: {
            action: "getContent",
            id: CONTENT_ID
          },
          success: handleContentLoadSuccess,
          error: handleContentLoadError
        });
      }

      // Verarbeitet den Erfolg der Inhaltsladung
      function handleContentLoadSuccess(data) {
        if (data === "Unbekannte ID") {
          console.error(data);
          return;
        }

        let $current = $("#current");
        let $next = $("#next");
        
        // Neue Sektion für den nächsten Inhalt erstellen
        let $newNext = $('<section id="next"></section>').html(data.html);

        // Animation
        $current.css("transform", "translateX(-100%)");
        $next.css("transform", "translateX(0)");
        $("main").append($newNext);

        // Aufräumen nach der Animation
        setTimeout(function() {
          $current.remove();
          $newNext.attr("id", "current");
        }, ANIMATION_DURATION);
      }

      // Verarbeitet Fehler bei der Inhaltsladung
      function handleContentLoadError(jqXHR, textStatus, errorThrown) {
        console.error('Fehler beim Laden des Inhalts:', textStatus, errorThrown);
      }

      // Initialer Aufruf und wiederholte Ladeintervalle
      function init() {
        loadMainContent();
        setInterval(loadMainContent, INTERVAL_DURATION);
      }

      init();
    });
  </script>
</body>
</html>

Edit: I’ve had good experiences with tinypng.com. They have all the necessary features for this task, but there is a limit of 500 images per month.

1 Like

Hi Schweminska,

Thank you very much for your response. Reducing the image size was also my first thought and could be a potential solution. I only used the larger images to force the crash within a shorter time frame.

I’ll try disabling caching in the browser and replace current.remove() with current.detach().remove().

Thanks again for your help so far!

Do you have in or out transitions for the Website widget?

To be honest, we’ve had a lot of issues with the Website widget, especially since Xibo never updates android.system.webview with their firmware releases. As a result, we’ve found luck in:
A) Using the Embedded widget instead of Website. The code would look something like this:

<iframe src="https://www.google.com" style="position:fixed; top:0; left:0; bottom:0; right:0; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;">
    Your browser doesn't support iframes
</iframe>

B) Manually upgrade your android.system.webview. This can be a pain to do since these players do not have the Google Play Framework installed on them. Once you figure it out, it’s not too bad, but nonetheless-- not as straightforward as it should be to keep these players relevant whilst running old Android OS versions.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.