Images and cache
Image and ImageBackground use the native image pipeline. Requests,
deduplication, disk I/O and cache-hit decoding run below the PHP component
layer; recycled views reject late results from an older source generation.
Since PAM Native 0.5.69, Android also retries bounded transient failures
while the image remains attached. A completed same-source request is reused
only when it still owns a drawable, so a first-visible VirtualizedList image
cannot remain blank until its cell is recycled.
Packaged assets
Section titled “Packaged assets”asset:// paths are relative to the PAM project root on Android and iOS:
<Image source="asset://assets/logos/brand.png" />This loads the checked-in assets/logos/brand.png. The runtime owns the
internal pam/ bundle prefix, so do not include it in application code.
The same rule applies to Image, ImageBackground, defaultSource,
loadingIndicatorSource, and packaged @font-face files. Empty paths,
directory traversal, queries, fragments, and malformed path segments are
rejected before a platform file API is called.
Production image
Section titled “Production image”use Pam\Native\ImageFit;use Pam\Native\ImageResizeMethod;use Pam\Native\MediaCachePolicy;use Pam\Native\MediaPriority;use Pam\Native\UI\Image;
$avatar = Image::make($user->avatarUrl) ->fit(ImageFit::Cover) ->defaultSource('asset://avatar-placeholder.png') ->loadingIndicatorSource('asset://avatar-loading.png') ->fadeDuration(180) ->resizeMethod(ImageResizeMethod::Resize) ->resize(512, 512) ->resizeMultiplier(2) ->progressiveRendering() ->sourceSet("{$user->avatarUrl} 1x, {$user->avatar2xUrl} 2x") ->headers(['Authorization' => "Bearer {$token}"]) ->cache(MediaCachePolicy::StaleWhileRevalidate) ->cacheKey("avatar:{$user->id}:v3") ->maxAge(30 * 24 * 60 * 60 * 1000) ->cacheTags(['avatar', "user:{$user->id}"]) ->priority(MediaPriority::Visible) ->maxCacheSize(64 * 1024 * 1024) ->pinOffline() ->onLoad(fn ($event) => $this->recordSize($event->width, $event->height)) ->onError(fn ($event) => $this->reportImageError($event->error));<Image :source="$user->avatarUrl" fit="cover" defaultSource="asset://avatar-placeholder.png" cache="stale-while-revalidate" cache-key="avatar:user-42:v3" cache-max-age="30d" cache-tags="avatar,user-42" cache-max-bytes="64mb" priority="visible" resize-width="512" resize-height="512" pin-offline on:cacheHit="cacheHit" on:cacheMiss="cacheMiss" on:cacheReady="cacheReady"/>ImageBackground
Section titled “ImageBackground”$hero = ImageBackground::make( 'asset://hero.webp', Column::make( Text::make('Build without accepting small boundaries'), Button::make('Start')->onPress($start), ),)->fit(ImageFit::Cover);Policies and events
Section titled “Policies and events”Available policies are none, memory, disk, memory-and-disk,
cache-first, network-first, cache-only, and
stale-while-revalidate. Cache events expose the stable key, loaded/total
bytes and disk origin. Image lifecycle events include load start, progress,
decoded size, error and load end.
The compact cachePolicy compatibility property also accepts default,
reload, force-cache, and only-if-cached. Since PAM Native 0.5.80,
memory-disk and memoryDisk are aliases for force-cache, so an Expo Image
port can keep its familiar spelling while still using PAM’s native
memory-plus-disk pipeline:
<Image :source="$avatarUrl" cachePolicy="memory-disk" fadeDuration="0"/>Animated GIF and animated WebP sources use the same request coalescing and
cache. On supported Android versions, PAM decodes them as a looping native
drawable; no WebView, JavaScript animation loop, or Lottie dependency is
required. Prefer animated WebP when the provider exposes both formats because
it normally transfers fewer bytes. In long pickers and feeds, place animated
images in a VirtualizedList so only visible rows are mounted.
Cache files use atomic activation, bounded downloads, checksum validation, least-recently-used eviction and offline pin protection. Adaptive-stream offline downloads remain a separate platform manifest/license workflow.
Storage settings and diagnostics
Section titled “Storage settings and diagnostics”PAM Native 0.5.34 exposes typed, asynchronous cache metrics and cleanup for
Android and iOS:
use Pam\Native\CacheUsage;use Pam\Native\System\Caches;
Caches::usage(static function (CacheUsage $usage): void { printf( "Images: %d, media: %d, temporary: %d bytes", $usage->imageBytes, $usage->mediaBytes, $usage->temporaryBytes, );});
Caches::clear( static function (CacheUsage $usage): void { printf("Freed %d bytes", $usage->freedBytes); },);Cleanup preserves media marked with pinOffline() by default. A destructive
“remove offline downloads” action can pass preserveOffline: false, preferably
after explicit user confirmation:
Caches::clear($onCleared, preserveOffline: false);Counting and disk cleanup run away from the UI thread.
DrawingCanvas
Section titled “DrawingCanvas”DrawingCanvas reuses the same source and cache pipeline, then places a
platform-native drawing surface over the aspect-fit image. It supports brush
and eraser modes, bounded coalesced points, tokenized undo/clear, and one
change event per completed stroke:
<DrawingCanvas :source="$photo" :value="$drawing" brushColor="#FFFFCC00" brushWidth="8" drawingMode="brush" :undoRequest="$undoRequest" :clearRequest="$clearRequest" on:change="updateDrawing"/>See Files and media for export through the off-UI-thread image editor.