Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
161451 stories
·
33 followers

Microsoft engineer explains why Windows gives new files the date of ones you deleted

1 Share

Suppose you have a file named articles.txt that you created yesterday. You delete it. A few seconds later, you create a completely different file named article.txt in the same folder. Then, strangely enough, when you open its Properties, Windows tells you that the new file was created yesterday!

Like many things in Windows, this too is decades old and not a bug, and it even has a catchy name: tunnelling.

The actual name is File System Tunnelling, and it is a feature of NTFS and FAT where, if you delete or rename a file and then quickly create another file with the same name in the same folder, the new file inherits metadata (like the original file’s creation timestamp or short/long name mapping).

But why would Windows knowingly make a brand-new file look like an old one? We went through a bunch of official documentation to find the answer.

Windows can remember a deleted file for a short time

File Creation date in File Explorer

Microsoft’s FileSystemInfo.CreationTime documentation says “NTFS-formatted drives may cache file meta-info, such as file creation time, for a short period of time. This process is known as file tunneling.”

Microsoft Engineer Raymond Chen wrote about this in 2005 and made a fun analogy to quantum tunnelling, from which the name was taken.

In quantum mechanics, tunnelling is when a particle can appear on the far side of an energy barrier it should not have had the energy to cross.

Chen joked that Windows’ file metadata pulled the same trick, where it got deleted on one side and reappeared on the other.

“In the case of file system tunneling, it is information that appears to violate the laws of classical mechanics. The information was destroyed (by deleting or renaming the file), yet somehow managed to reconstruct itself on the other side of a temporal barrier.”

He also mentioned that the Windows 95 developer who built the feature got carried away with the analogy and named the internal data structures quarks!

How File System Tunnelling works?

  • When a file is deleted or renamed, Windows creates an entry in the tunnel cache.
  • If you create a new file with the same name in the same directory within a short time window, Windows applies the cached metadata (creation time, SFN/LFN mapping) to the new file.
  • This cache is per‑volume and automatically clears older entries when full.

Before you get privacy and security concerns, note that the deleted file is gone and its contents do not come back. What Windows preserves for 15 seconds is the metadata, which includes the creation time and the association between a file’s long filename and its 8.3 short filename.

Also, the cache does not last forever. It belongs to the directory, is temporary, and only kicks in when the right create or rename operations happen within its window. A new file will not automatically inherit an old timestamp just because it has the same name of something deleted last month.

If you are really concerned about someone recovering deleted files after resetting Windows, Microsoft has a new Data Sanitization option in Cloud Rebuild.

Anyway, the real question is: why does file system tunneling even exist?

Microsoft didn’t create file tunneling to confuse you

When we use a program like Word to edit a document we created yesterday and then save it, we would expect the file to retain its original creation date, because we were editing the file instead of creating it.

However, as Chen said, “But internally, many programs save a file by performing a combination of save, delete, and rename operation”

This means many applications do not modify an existing file in place. A program may create a temporary file with the updated content, delete the original, then rename the temporary file to the original name. This is called the Safe save method.

To us, it looks like editing and saving a document. But Windows saw a file created, deleted, and renamed.

If tunnelling wasn’t there, the replacement file would suddenly get a brand-new creation date, even though we didn’t create a new document.

This isn’t the only reason, though. Chen’s other example involves older programs that only understood 8.3 short filenames. If one of those replaced “File with long name.txt” without preserving the long and short name association, the file could lose its friendly name completely and end up looking like its DOS-era short name instead.

In 16‑bit applications, only short file names (SFN) are usable. Tunneling preserves the link between SFN and LFN (long file names) when files are renamed or recreated.

Basically, File system tunneling exists to support the safe save pattern used by applications and to maintain 8.3 short name/long name compatibility.

Which paired operations can cause the file name “name” to be tunneled

Microsoft’s FltGetTunneledName documentation describes the mechanism as a per-volume tunnel cache.

It lists the operation pairs that can trigger tunneling.

  • delete(name) / create(name)
  • delete(name) / rename(source, name)
  • rename(name, newname) / create(name)
  • rename(name, newname) / rename(source, name)

If you’re interested, an older Microsoft KB article, originally written for Windows NT and XP, mentions how to adjust or disable the 15-second default cache window for tunnelling through the registry.

So, the next time a new file claims to be several days old, Windows probably is not broken. It may just be doing exactly what Microsoft designed it to do.

The post Microsoft engineer explains why Windows gives new files the date of ones you deleted appeared first on Windows Latest

Read the whole story
alvinashcraft
47 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Share State Across Dart Isolates Without Losing Your Mind: Enter shared_map

1 Share

This is Part 3 of the Dart and Flutter series—practical guides, architectural deep dives, and hard-earned engineering lessons from the field. Each article is completely standalone.

Dart’s concurrency model is built on Isolates. Unlike threads in Java, C++, or Go, Dart isolates share no memory. Each isolate has its own private heap and its own single-threaded event loop.

This "share-nothing" model is a brilliant design decision. It completely eliminates data races, deadlocks, mutex contention, and tricky thread-synchronization bugs.

Until, of course, you actually need to share data across isolates.

Imagine this common production scenario:

You’re building a Flutter app that crunches heavy data in the background—perhaps resizing multiple images, decoding massive JSON payloads, computing cryptographic hashes, or running complex ML calculations. To keep your UI silky smooth at 120 FPS, you offload the work to background isolates using Isolate.run.

Now suppose all these concurrent background workers need access to a shared, in-memory cache (like parsed metadata, authentication tokens, or shared computation results) to avoid duplicate work.

How do you do that in Dart?

Traditionally, you only had two bad choices:

  1. Serialize and copy the whole data structure back and forth across isolate boundaries every time. For large maps or high-frequency operations, this burns CPU and produces massive GC pressure.
  2. Hand-roll a message-passing server using ReceivePort and SendPort. You have to invent custom request/response DTOs, generate unique request correlation IDs, wire up response completers, and write 150 lines of brittle plumbing just to perform a simple key-value lookup.

There is a third, vastly superior option that almost nobody talks about: package:shared_map.

What is shared_map?

Created by veteran Dart engineer Graciliano M. Passos, shared_map provides a versatile, synchronized Map data structure designed specifically to be shared across Dart isolates and asynchronous workflows.

Here is what makes it an architectural gem:

  • Zero Dependencies: It is pure, clean Dart with zero third-party dependencies.
  • 160 / 160 Pub Points: Flawless quality score on pub.dev and fully Dart 3 compatible.
  • Universal Platform Support: Runs anywhere Dart runs—iOS, Android, macOS, Windows, Linux, Web, and backend CLI/servers.
  • Familiar Map Semantics: You interact with it using standard async key-value methods like get(), put(), putIfAbsent(), and update().

Instead of you manually orchestrating ports, shared_map manages the cross-isolate communication protocol transparently under the hood.

How It Works: The Reference Pattern

The core mental model of shared_map is dead simple:

  1. Main Instance: You create a SharedMap on your primary isolate (like your Flutter UI thread or main server loop). This instance acts as the authoritative source of truth.
  2. Shared Reference: You call .sharedReference() to generate a lightweight, serializable token.
  3. Auxiliary Instance: You pass that lightweight token across an isolate boundary (e.g. into Isolate.run). Inside the isolate, you reconstruct a proxy instance using SharedMap.fromSharedReference(ref).

Any reads, writes, or mutations performed by the worker isolate are automatically dispatched back to the main instance and synchronized across all isolates!

See It In Action

Let’s write a complete, self-contained example. We'll simulate multiple concurrent worker isolates crunching data, reading from a shared cache, and populating cache entries on the fly:

import 'dart:isolate';
import 'package:shared_map/shared_map.dart';

void main() async {
  // 1. Create a SharedStore and a SharedMap on the main isolate
  final store = SharedStore('app_cache');
  final userCache = await store.getSharedMap<String, String>('users');

  // Seed an initial value
  await userCache!.put('user_101', 'Randal (Admin)');

  // 2. Extract the lightweight, serializable reference
  final cacheReference = userCache.sharedReference();

  print('--- Spawning Background Worker 1 ---');

  // 3. Pass the reference into a background isolate
  final worker1Result = await Isolate.run(() async {
    // Reconstitute the synchronized map proxy
    final workerMap = SharedMap<String, String>.fromSharedReference(cacheReference);

    // Read the value previously stored by the main isolate:
    final user = await workerMap.get('user_101');
    print('[Worker 1] Read from shared cache: $user');

    // Put a new value into the shared cache from this background worker:
    await workerMap.put('user_102', 'Wilhelm (Engineer)');
    return 'Worker 1 finished';
  });

  print(worker1Result);

  print('--- Spawning Background Worker 2 ---');

  // 4. Spawn a second isolate to prove cross-isolate synchronization
  final worker2Result = await Isolate.run(() async {
    final workerMap = SharedMap<String, String>.fromSharedReference(cacheReference);

    // Worker 2 can immediately read what Worker 1 just wrote!
    final user102 = await workerMap.get('user_102');
    print('[Worker 2] Read value written by Worker 1: $user102');

    // Use putIfAbsent atomically
    final user103 = await workerMap.putIfAbsent('user_103', 'Guest User');
    return '[Worker 2] Added: $user103';
  });

  print(worker2Result);

  // 5. Verify the main isolate reflects all updates
  print('--- Back on Main Isolate ---');
  print('Total entries in cache: ${await userCache.length()}');
  print('user_102 on main: ${await userCache.get('user_102')}');
  print('user_103 on main: ${await userCache.get('user_103')}');
}

The Console Output

--- Spawning Background Worker 1 ---
[Worker 1] Read from shared cache: Randal (Admin)
Worker 1 finished
--- Spawning Background Worker 2 ---
[Worker 2] Read value written by Worker 1: Wilhelm (Engineer)
[Worker 2] Added: Guest User
--- Back on Main Isolate ---
Total entries in cache: 3
user_102 on main: Wilhelm (Engineer)
user_103 on main: Guest User

Notice what just happened:

  • Two independent background isolates communicated and shared data back to the main thread.
  • Not a single SendPort, ReceivePort, Completer, or serialization boilerplate line was written.

Superpower: Local Read Caching with SharedMapCached

If your worker isolates perform thousands of rapid reads, you might not want every single get() call to perform a cross-isolate message dispatch.

shared_map includes a built-in subclass called SharedMapCached:

final cachedWorkerMap = SharedMapCached<String, String>.fromSharedReference(
  cacheReference,
  // Cache items locally in this isolate for high-throughput reads
  timeout: const Duration(seconds: 30),
);

When you query an existing key with SharedMapCached, it caches the value locally in the worker's isolate heap. If subsequent reads occur within the timeout window, they resolve instantly without cross-isolate latency.

Grouping Maps with SharedStore

In complex applications, you rarely have just one cache. You might have:

  • An image cache (SharedMap<String, Uint8List>)
  • A user profile cache (SharedMap<String, UserProfile>)
  • A rate limiter map (SharedMap<String, int>)

Instead of passing dozens of individual references around, you pass a single SharedStoreReference:

// Main thread:
final store = SharedStore('global_store');
await store.getSharedMap<String, String>('tokens');
await store.getSharedMap<String, int>('rate_limits');

final storeRef = store.sharedReference();

// Inside any background isolate:
await Isolate.run(() async {
  final workerStore = SharedStore.fromSharedReference(storeRef);

  // Dynamically resolve any map registered under this store:
  final tokens = await workerStore.getSharedMap<String, String>('tokens');
  final rateLimits = await workerStore.getSharedMap<String, int>('rate_limits');

  // ...
});

Senior Engineering Wisdom: When to Use (and Not Use) shared_map

As with any tool, understanding the architectural sweet spot is key.

✅ When to Reach for shared_map:

  1. CPU-Intensive Worker Coordination: When running pools of background isolates (Isolate.run or persistent worker isolates) that need shared lookups.
  2. In-Memory Deduping & Caching: Preventing concurrent workers from calculating or downloading the exact same asset twice.
  3. Cross-Isolate Metrics & Counters: Collecting stats, telemetry, or rate-limit tokens across multiple threads.

⚠️ When NOT to Use shared_map:

  1. Persistent On-Disk Storage: shared_map is an in-memory data structure. If your data must survive app restarts, use SQLite, Drift, or a persistent key-value store.
  2. Single-Isolate Applications: If all your code runs on the root UI isolate, a standard Dart Map<K, V> or reactive Signal is all you need—there's no reason to pay the asynchronous abstraction cost.

Summary

Dart's isolate architecture keeps our code safe from concurrency bugs, but you shouldn't have to write hundreds of lines of port plumbing just to share an in-memory cache across worker tasks.

By bringing in shared_map:

  1. You keep isolates isolated and UI threads responsive.
  2. You eliminate manual SendPort and ReceivePort spaghetti code.
  3. You get atomic, synchronized key-value storage with zero external dependencies.

Add shared_map: ^1.1.9 to your pubspec.yaml and stop reinventing isolate messaging from scratch.

What's your take?

How do you currently coordinate data between background isolates in your Flutter apps? Have you been writing custom ports, or relying on Isolate.run return values? Let me know in the comments below!

Randal L. Schwartz is a Google Developer Expert (GDE) for Dart & Flutter and veteran software architect.

Read the whole story
alvinashcraft
49 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Dart Enhanced Enums Are Secretly Factories: Unlocking Constructor Tearoffs

1 Share

This is Part 2 of the Dart and Flutter series—practical guides, architectural deep dives, and hard-earned engineering lessons from the field. Each article is completely standalone.

How many times have you written (or reviewed) a piece of code that looks like this?

NotificationWidget buildNotification(NotificationType type, NotificationData data) {
  switch (type) {
    case NotificationType.email:
      return EmailNotificationWidget(data);
    case NotificationType.sms:
      return SmsNotificationWidget(data);
    case NotificationType.push:
      return PushNotificationWidget(data);
  }
}

Or worse, a dedicated NotificationWidgetFactory class containing a 40-line switch statement or a mutable Map<NotificationType, Function> registry.

It feels routine. It’s what we were taught in classic OOP textbooks. But it introduces subtle friction:

  • The enum NotificationType knows nothing about the widgets it represents.
  • The factory switch ladder must be updated every time a new case is added.
  • The creation logic is split across multiple files and layers.

What if your enum wasn't just a list of identifiers, but was itself the polymorphic factory?

By marrying two features of modern Dart—Enhanced Enums and Constructor Tearoffs—you can delete the switch ladders and turn your enum values into self-instantiating factories in under 15 lines of code.

The Two Ingredients: A Brief History

To understand how clean this pattern is, we have to appreciate two language features that quietly revolutionized Dart over the last couple of years:

1. Constructor Tearoffs (Dart 2.15+)

Before Dart 2.15, if you wanted to pass a constructor as a first-class function, you had to wrap it in an awkward lambda:

// The old, clunky way:
final builders = [(data) => EmailNotification(data)];

Dart 2.15 introduced Constructor Tearoffs. Constructors became first-class closures. You can reference default constructors using .new, or named constructors directly by name:

// The modern Dart way:
final builders = [EmailNotification.new];
final parsers = [User.fromJson];

2. Enhanced Enums (Dart 2.17+)

Before Dart 2.17, Dart enums were glorified integers. They had an index and a name, and virtually nothing else.

With Enhanced Enums, enums gained full class powers:

  • They can declare final fields.
  • They can have const constructors.
  • They can implement interfaces and mixins.
  • They can define methods, getters, and operator overloads.

When you put constructor tearoffs inside enhanced enums, something magical happens.

The Fusion: Enums as Self-Instantiating Factories

Let’s model a common domain scenario: a document rendering engine. We have different document types that share a common interface:

abstract class Document {
  String get title;
  void render();
}

class PdfDocument implements Document {
  @override
  final String title;
  PdfDocument(this.title);

  @override
  void render() => print('Rendering PDF: $title');
}

class MarkdownDocument implements Document {
  @override
  final String title;
  MarkdownDocument(this.title);

  @override
  void render() => print('Rendering Markdown: $title');
}

class HtmlDocument implements Document {
  @override
  final String title;
  HtmlDocument(this.title);

  @override
  void render() => print('Rendering HTML: $title');
}

Now, instead of writing an external DocumentFactory or a switch statement, we declare an Enhanced Enum where each enum member holds a tearoff reference to its class constructor:

enum DocumentType {
  pdf(PdfDocument.new),
  markdown(MarkdownDocument.new),
  html(HtmlDocument.new);

  // A field holding a function that creates a Document given a String title
  final Document Function(String title) create;

  const DocumentType(this.create);
}

Look closely at DocumentType:

  1. Document Function(String title) create: A strongly typed function signature stored as a final field.
  2. pdf(PdfDocument.new): We pass the constructor tearoff directly to the enum value.
  3. const DocumentType(this.create): The constructor is const, so the entire enum remains compile-time constant!

How You Use It

Instantiating a polymorphic object is now as simple as calling the field on the enum instance:

void main() {
  const selectedType = DocumentType.markdown;

  // Polymorphic instantiation with ZERO switch statements:
  final doc = selectedType.create('Architecture_Notes.md');

  doc.render(); // Output: Rendering Markdown: Architecture_Notes.md
}

No switch statement. No map lookups. No reflection. If you add a new enum value (e.g. epub), the compiler forces you to supply a matching constructor tearoff right there. You cannot accidentally forget to handle it.

Real-World Example: Polymorphic API Payload Parsers

This pattern shines when deserializing polymorphic JSON payloads (like webhooks, analytics events, or push notifications).

Imagine an incoming stream of server events:

{
  "type": "login",
  "payload": {"userId": "usr_42", "timestamp": 1711000000}
}

We have distinct payload models:

abstract class EventPayload {}

class LoginPayload implements EventPayload {
  final String userId;
  LoginPayload.fromJson(Map<String, dynamic> json) : userId = json['userId'] as String;
}

class PurchasePayload implements EventPayload {
  final double amount;
  PurchasePayload.fromJson(Map<String, dynamic> json) : amount = (json['amount'] as num).toDouble();
}

Instead of a bulky JSON parsing switch, our enum maps incoming strings directly to the named constructor tearoff (.fromJson):

enum EventType {
  login(LoginPayload.fromJson),
  purchase(PurchasePayload.fromJson);

  final EventPayload Function(Map<String, dynamic>) fromJson;
  const EventType(this.fromJson);

  static EventType? fromString(String name) =>
      EventType.values.where((e) => e.name == name).firstOrNull;
}

Now, your dispatcher parses any incoming event in two clean lines:

EventPayload parseEvent(String typeName, Map<String, dynamic> rawPayload) {
  final eventType = EventType.fromString(typeName) ?? 
      (throw UnsupportedError('Unknown event: $typeName'));

  return eventType.fromJson(rawPayload);
}

Real-World Example: Flutter Widget Builders

In Flutter applications, you frequently have a selection control (tabs, filters, or segmented buttons) that drives which widget to render:

enum DashboardView {
  analytics(AnalyticsView.new),
  activity(ActivityView.new),
  settings(SettingsView.new);

  final Widget Function({Key? key}) builder;
  const DashboardView(this.builder);
}

In your widget tree:

class DashboardScreen extends StatelessWidget {
  final DashboardView currentView;
  const DashboardScreen({super.key, required this.currentView});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: currentView.builder(),
    );
  }
}

When you add a 4th tab tomorrow, you don't hunt through widget tree switch statements—you simply declare it on the enum.

A Senior Perspective: When NOT to Use This Pattern

Every pattern has architectural boundaries. While enum constructor tearoffs are powerful, here are two caveats to keep in mind:

1. Beware of Layer Inversion (Separation of Concerns)

If your enum lives in your pure Dart Domain Layer (core business logic), do not attach Flutter widget constructor tearoffs to it. Doing so couples your domain models to package:flutter.

  • Good: An enum in the presentation layer mapping UI modes to widget constructors.
  • Good: An enum in the data layer mapping API event types to DTO constructors.
  • Bad: A domain entity enum importing flutter/material.dart.

2. When to Prefer Dart 3 Sealed Classes & Pattern Matching

Dart 3 introduced sealed class hierarchies and exhaustive switch expressions:

// Alternative: Dart 3 pattern matching
Widget buildView(DashboardView view) => switch (view) {
  DashboardView.analytics => const AnalyticsView(),
  DashboardView.activity => const ActivityView(),
  DashboardView.settings => const SettingsView(),
};

Which should you choose?

  • Use Enum Constructor Tearoffs when the creation parameters are identical, the association between the enum and the class is 1:1, and you want self-contained encapsulation with zero boilerplate.
  • Use Sealed Classes & Pattern Matching when each subclass takes radically different parameters, when cases have unique construction logic, or when you want to avoid coupling the enum to the concrete implementations.

Conclusion

Enhanced Enums and Constructor Tearoffs are two of modern Dart's finest language ergonomics. When combined, they eliminate entire classes of boilerplate:

  1. Self-documenting: The enum member explicitly declares the constructor that builds it.
  2. Compile-time safe: Missing a constructor is impossible; the compiler will not let you compile an enum member without satisfying the signature.
  3. Zero switch statements: Replaces sprawling factory classes with a clean, single-line invocation.

Next time you catch yourself writing a 30-line switch statement just to instantiate a class from an enum value, pause. Let the enum do the work.

What's your take?

Have you started using constructor tearoffs in your enums, or do you prefer Dart 3 switch expressions? Let me know in the comments below!

Randal L. Schwartz is a Google Developer Expert (GDE) for Dart & Flutter and veteran software architect.

Read the whole story
alvinashcraft
49 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Links For You (9/20/26)

1 Share

Happy "Football is Back" season to those of you who celebrate. I'm currently watching my Saints take on the Ravens (who are also a favorite of mine) and hoping for our first win. The last few weeks have been incredibly busy (I feel like I always say that, sorry) with a trip for work that then morphed into a short vacation with my wife and I which included my first Blizzcon (which is freaking cool as hell) and our first visit to Disneyland. (We've been to Disney World a few times.) I think we both agreed that Disney World is cooler, but the crowds and - most importantly - the weather - was much better in California.

Stormtroopers

RSS Lookup

First up for the links today is RSS Lookup, a simple web site that lets you paste in a URL and see if it has a RSS feed. Not every site does a good job of letting you know about their RSS options so this can make it easier. Most likely I think the bookmarklet will be more useful to folks.

If your curious, here's the meta tag used to signify a site's feed:

<link rel="alternate" type="application/rss+xml" 
title="Your Site Title - RSS Feed" href="https://example.com" />

Interfaces, a collection by Ron Domingue

Ron is someone I've known for a while, a local down here in Louisiana, who has done some incredibly stunning visual works. His Interfaces is a collection of various UI interfaces for different types of data. I'd be hard pressed to pick a favorite, but Landfall is a stunning visualization of hurricane tracks and their landfall.

Landfall

Remember Imagemaps?

Imagemaps are one of those old web techs that used to be everywhere, and then disappeared. In case you don't remember, the idea was that one image on a web page, when clicked, could have multiple different destinations based on where you clicked. Typically this was defined in HTML with coordinates mapping to URLs. But you could also handle the location on the server side as well. In that form, the coordinates are included in the URL and your server side tech has to handle figuring out what goes where.

This post, "Today I Rescued 7,234 Old GIFs", by Dan Q explores how he attempted (and succeeded) in scraping a bunch of Gif icons for an old directory.

Not gonna lie - kinda miss the old web. :)

Just For Fun

Ok, usually I share cool music videos here, but today I want to share something different. My father-in-law shared this short with us and while it's marked as comedy, it's a pretty deep 30-ish minute short staring Jane Kaczmarek. It's definitely worth your time!

Play Video

Read the whole story
alvinashcraft
49 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

Android Weekly Issue #745

1 Share
Articles & Tutorials
Sponsored
Your agents are getting good at fixing things, but humans still have to monitor, review, and assign issues first. Triage by Runway pulls every mobile issue into one inbox: test results, beta feedback, reviews, crashes, and more. Then auto-assign, or let agents connect via MCP to pick up fixes.
alt
Adit Lal explains ComposeProof, an MCP server giving AI coding agents ways to see and verify Compose UI.
Nacho Carrión explains how Gradle's dependency resolution causes silent runtime crashes in KMP projects, especially on iOS.
Sponsored
Debugging mobile apps is weird: intermittent connections, mid-onboarding drop-offs, edge cases on devices you've never tested. bitdrift captures 100% of data, unsampled and in real time, so it’s immediately queryable by engineers and agents. Try bitdrift: mobile observability for the real world.
alt
Oğuzhan Aslan explains LiteRT-LM's Engine/Session model for on-device chat, covering streaming, tool calling, multimodal input, and thinking mode.
Rotem Meidan examines why Chrome, Firefox, WhatsApp, and Discord split Android apps into separate processes for isolation and recovery.
Jaewoong Eum walks through building custom purchase flows and paywalls with RevenueCat's Android Purchases SDK.
Akshay Nandwana builds a camera-aware Voice AI Android app using Agora Conversational AI, Gemini Live, and Jetpack Compose.
RayLabs examines native Android update options — In-App Updates, remote config, server-driven UI — and their security boundaries.
Place a sponsored post
We reach out to more than 80k Android developers around the world, every week, through our email newsletter and social media channels. Advertise your Android development related service or product!
alt
News
Gradle explains prioritizing agent-facing skills and benchmarking over defaulting Configuration Cache in Gradle 10.
Google unveils Android Bench 2.0, adding long-horizon tasks, agentic evaluation, and continuous scoring for AI coding models.
Google releases stable AndroidX Security State libraries, giving apps component-level device patch and vulnerability visibility.
Touchlab releases Kermit 2.2.0, adding WasmWasi support plus a new kermit-coil module for routing Coil 3 logs.
JetBrains opens its annual Kotlin Developer Survey for feedback on the language and tooling.
Videos & Podcasts
Kotlin by JetBrains covers Kotlin 2.4.20's new standard library additions, iOS and Wasm/JS improvements.
Philipp Lackner demonstrates certificate pinning to protect Android app network traffic from man-in-the-middle attacks.
Firebase demonstrates generating low-latency Gemini text-to-speech audio with emotion control and multi-speaker dialogue via Firebase AI Logic.
Read the whole story
alvinashcraft
50 minutes ago
reply
Pennsylvania, USA
Share this story
Delete

25 agent skills to improve your workflow in GitHub Copilot | Matt Pocock | GitHub Copilot Day

1 Share
From: GitHub
Duration: 19:51
Views: 7,528

Want to get more consistent results from your AI coding agents? In this GitHub Copilot Day session, Matt Pocock walks through his popular open-source collection of Agent Skills. Learn how skills like "Grill with Docs", Dexter Horthy’s "Show Me", and "Code Review" help align agents before implementation, generate visual pull requests, and catch architecture issues early.

▬▬▬▬▬▬ WANT TO LEARN MORE? 🚀 ▬▬▬▬▬▬

Matt Pocock’s “AI Skills for Real Engineers” https://github.com/mattpocock/skills
Get hands-on with the Copilot app https://gh.io/ghcpdaycopilotapp
Check out Copilot app resources https://gh.io/ghcpdaycopilotappresources

▬▬▬▬▬▬ TIMESTAMPS ⌚ ▬▬▬▬▬▬

0:00 Intro: the skills repo
0:48 Grill with Docs: aligning with the agent
1:32 Real work in the course video manager
2:16 Grilling issue 1612 live
3:23 Reaching shared understanding faster
4:33 The resulting pull request
5:40 The "Show Me" skill for visual PRs
7:11 Making PRs worth a human's time
8:01 The Code Review skill in action
9:33 Standards and spec check findings
10:21 Code review as part of implementation
11:27 Improve Codebase Architecture skill
12:59 Plain-English output with "potato"
14:04 From report to spec and tickets
15:55 Implement Spec with parallel worktrees
17:28 New skill: Retro
19:22 Wrap-up

#GitHubCopilot #AIAgent #GitHub

Stay up-to-date on all things GitHub by connecting with us:

YouTube: https://gh.io/subgithub
Blog: https://github.blog
X: https://twitter.com/github
LinkedIn: https://linkedin.com/company/github
Insider newsletter: https://resources.github.com/newsletter/
Instagram: https://www.instagram.com/github
TikTok: https://www.tiktok.com/@github

About GitHub
It’s where over 180 million developers create, share, and ship the best code possible. It’s a place for anyone, from anywhere, to build anything—it’s where the world builds software. https://github.com

Read the whole story
alvinashcraft
50 minutes ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories