SmartTube Crash Mitigation Strategies for Low-End Android TV Devices

SmartTube prevents OutOfMemoryError crashes on low-end Android TV devices through runtime preference flags that reduce Glide cache sizes, disable Leanback animations, and scale thumbnail resolutions dynamically based on user-configured constraints.

SmartTube is an open-source YouTube client for Android TV optimized to operate efficiently on hardware with limited RAM and processing power. The yuliskov/SmartTube repository implements targeted crash mitigation strategies in smarttubetv that detect resource constraints via AppPreferenceManager and automatically reduce memory pressure through configurable caching, image loading limits, and UI simplification.

Runtime Memory Configuration via AppPreferenceManager

The central configuration hub for crash mitigation resides in smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/ui/dialogs/AppPreferenceManager.java. This class wraps Android's SharedPreferences to expose runtime flags that downstream components query before allocating memory or rendering animations.

Low Memory Mode Detection

The KEY_LOW_MEMORY_MODE constant enables the application to adopt aggressive conservation tactics when activated. The isLowMemoryMode() method returns the current state, while setLowMemoryMode() persists user preferences:

public class AppPreferenceManager {
    private static final String KEY_LOW_MEMORY_MODE = "low_memory_mode";
    
    public boolean isLowMemoryMode() {
        return mPrefs.getBoolean(KEY_LOW_MEMORY_MODE, false);
    }
    
    public void setLowMemoryMode(boolean enabled) {
        mPrefs.edit().putBoolean(KEY_LOW_MEMORY_MODE, enabled).apply();
    }
}

Animation and Quality Controls

Complementing the memory flag, KEY_DISABLE_ANIMATIONS and KEY_MAX_IMAGE_QUALITY provide granular control over rendering overhead. The isAnimationsDisabled() method allows fragments to bypass transition animations, while getMaxImageQuality() returns the user-defined resolution ceiling for thumbnail loading operations.

Glide Cache Management and Bitmap Constraints

Image loading represents the primary memory risk in media applications. SmartTube addresses this through smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/util/GlideCachingModule.java, which configures the Glide library's caching behavior to prevent OutOfMemoryError exceptions.

Disk Cache Limitation

The module constrains disk cache to 100 MB—down from Glide's default 250 MB—to preserve storage space on devices with limited internal memory:

public class GlideCachingModule extends AppGlideModule {
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        int cacheSize100MegaBytes = 1024 * 1024 * 100;
        builder.setDiskCache(new InternalCacheDiskCacheFactory(context, cacheSize100MegaBytes));
    }
}

Memory Pool Reduction

For devices operating in low-memory mode, the module contains infrastructure for halving both the memory cache and bitmap pool sizes using LruResourceCache and LruBitmapPool. When activated via isLowMemoryMode() checks, these adjustments reduce RAM consumption by 50% during image-intensive grid scrolling operations.

Dynamic UI Adaptation in VideoCardPresenter

The Leanback UI layer implements resolution scaling in smarttubetv/src/main/java/com/liskovsoft/smartyoutubetv2/tv/presenter/VideoCardPresenter.java. When binding video thumbnails, the presenter applies RequestOptions.override() to constrain bitmap dimensions and prevent excessive memory allocation:

@Override
public void onBindViewHolder(ViewHolder viewHolder, Object item) {
    VideoItem video = (VideoItem) item;
    ImageCardView cardView = (ImageCardView) viewHolder.view;
    cardView.setTitleText(video.getTitle());
    cardView.setContentText(video.getChannelTitle());
    
    Glide.with(mContext)
        .load(video.getThumbnailUrl())
        .apply(new RequestOptions().override(720, 405))
        .into(cardView.getMainImageView());
}

By integrating with AppPreferenceManager.getMaxImageQuality(), the application can dynamically adjust override dimensions—reducing to 480×270 or 320×180 when quality preferences demand conservation on low-end chipsets.

User-Facing Preference Controls

User configuration resides in smarttubetv/src/main/res/xml/preferences.xml, exposing the mitigation flags through standard Android PreferenceScreen components:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <SwitchPreference
        android:key="low_memory_mode"
        android:title="Low Memory Mode"
        android:summary="Reduce memory usage and image quality for low-end devices" />
    <SwitchPreference
        android:key="disable_animations"
        android:title="Disable Animations"
        android:summary="Turn off UI animations to improve performance" />
    <ListPreference
        android:key="max_image_quality"
        android:title="Maximum Image Quality"
        android:summary="Set the maximum image resolution for thumbnails"
        android:defaultValue="high" />
</PreferenceScreen>

These settings write directly to the SharedPreferences instance managed by AppPreferenceManager, enabling immediate runtime behavior changes without application restarts.

Summary

  • AppPreferenceManager centralizes runtime configuration through SharedPreferences, exposing isLowMemoryMode() and isAnimationsDisabled() for conditional resource allocation
  • GlideCachingModule caps disk cache at 100 MB via InternalCacheDiskCacheFactory and provides hooks to halve memory cache via LruResourceCache when constrained
  • VideoCardPresenter leverages Glide's RequestOptions.override() to scale thumbnails dynamically, preventing large bitmap decodes on devices with limited RAM
  • preferences.xml surfaces granular controls to users via SwitchPreference and ListPreference XML definitions for low_memory_mode, disable_animations, and max_image_quality

Frequently Asked Questions

How does SmartTube detect low-end devices?

SmartTube relies on explicit user preference detection rather than automatic hardware profiling. The AppPreferenceManager.isLowMemoryMode() method checks the low_memory_mode boolean in SharedPreferences, allowing users to manually indicate resource constraints or enabling automatic toggles through future build adaptations based on Build.VERSION or memory class detection.

What is the default cache size for images in SmartTube?

According to GlideCachingModule.java, SmartTube configures a 100 MB disk cache—reduced from Glide's default 250 MB—through the InternalCacheDiskCacheFactory. The memory cache and bitmap pool can be further constrained to 50 MB each when the low-memory preference is active, as indicated by the commented LruResourceCache and LruBitmapPool initializations.

Can animations be disabled completely in SmartTube?

Yes. When the disable_animations preference is enabled via AppPreferenceManager.setDisableAnimations(true), the application bypasses Leanback transition animations and presenter-level UI effects. This reduces CPU load and eliminates frame drops on underpowered chipsets by skipping costly property animator operations during card focus changes and fragment transitions.

Does SmartTube reduce video quality or just thumbnail quality?

The current implementation shown in the source focuses on thumbnail resolution through VideoCardPresenter and Glide's override options. The max_image_quality preference specifically governs RequestOptions.override() dimensions for card images in the browse UI, while video playback quality remains controlled through separate stream selection logic in the playback engine.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →