A robust Flutter plugin for terminating and restarting your app with extensive customization options. Perfect for implementing dynamic updates, clearing app state, or refreshing your app's UI.
The demo showcases:
- ๐ UI-only restart for quick refreshes
- ๐ Full app termination and restart
- ๐งน Data clearing with preservation options
- ๐ Customizable confirmation dialogs
- โก Smooth transitions and animations
-
โจ Three Restart Modes:
-
UI-only Restart: (~200ms)
- Recreates activities/views while maintaining connections
- Perfect for theme changes, language switches
- Preserves network connections and background tasks
- Faster execution with minimal disruption
-
Full Process Restart: (~800ms)
- Complete app termination and restart
- Ideal for updates, security-related changes
- Cleans up all resources and states
- Ensures fresh start with no residual state
-
With Confirmation Dialog: (+50ms)
- Shows a customizable confirmation dialog
- User can choose to proceed or cancel
- Supports both UI-only and full restart
- Perfect for user-initiated actions
-
-
๐งน Smart Data Management:
- Configurable data clearing during restart
- Granular control over data preservation
- Secure handling of sensitive information
-
๐ Security Features:
- Optional keychain data preservation
- Secure user defaults handling
- Clean process termination
-
๐ฑ Platform Support:
- โ Android: Full support with activity recreation
- โ iOS: Compliant with App Store guidelines
-
๐ซ User Experience:
- Built-in confirmation dialogs
- Customizable messages and buttons
- Smooth transitions and animations
dependencies:
terminate_restart: ^1.0.7
No special permissions are required for either Android or iOS! The plugin uses only standard platform APIs:
- No additional permissions needed in AndroidManifest.xml
- Uses standard Activity lifecycle methods
- No protected features accessed
- No special entitlements needed in Info.plist
- No additional capabilities required
- Uses standard UIKit methods
Get up and running with Terminate Restart in minutes:
- Add Dependency
dependencies:
terminate_restart: ^1.0.7
- Import Package
import 'package:terminate_restart/terminate_restart.dart';
- Basic Usage
// UI-only refresh (fast, maintains connections)
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: false,
),
);
// Full app restart with confirmation
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: true,
),
mode: RestartMode.withConfirmation,
dialogTitle: 'Restart Required',
dialogMessage: 'Do you want to restart the app?',
);
This plugin follows Apple's App Store guidelines regarding app termination:
-
User-Initiated Actions: The plugin only performs termination in response to explicit user actions (e.g., logout, clear data, etc.).
-
Graceful Shutdown: On iOS, the plugin uses approved APIs to ensure graceful app termination:
- Uses
exit(0)
for clean termination - Properly saves state and closes resources
- Follows iOS application lifecycle
- Uses
-
Restart Mechanism: The restart functionality complies with iOS guidelines by:
- Using approved launch mechanisms
- Preserving user preferences when requested
- Maintaining system integrity
-
Data Handling: When clearing data:
- Respects iOS data protection
- Properly handles keychain items
- Maintains necessary system files
Note: While Android allows direct app termination, iOS termination is handled through system-approved methods to ensure App Store compliance.
- Initialize the Plugin
void main() {
WidgetsFlutterBinding.ensureInitialized();
// Initialize with default settings
TerminateRestart.instance.initialize();
runApp(MyApp());
}
- Basic Usage
// UI-only restart (fast, maintains connections)
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: false,
),
);
// Full app restart (clean slate)
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: true,
),
);
// UI-only restart with confirmation
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: false,
),
mode: RestartMode.withConfirmation,
dialogTitle: 'Refresh UI',
dialogMessage: 'Do you want to refresh the app UI?',
);
// Full app restart with confirmation
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: true,
),
mode: RestartMode.withConfirmation,
dialogTitle: 'Restart App',
dialogMessage: 'Do you want to restart the app?',
);
Scenario | Description | Code Example |
---|---|---|
UI Refresh | Quick UI restart without termination | ```dart |
await TerminateRestart.instance.restartApp( | ||
options: const TerminateRestartOptions( |
terminate: false,
),
);| | Full Restart | Complete app termination and restart |
dart
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: true,
),
);| | Clear Data | Restart with data clearing |
dart
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: true,
clearData: true,
),
);| | Preserve Settings | Clear data but keep settings |
dart
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: true,
clearData: true,
preserveKeychain: true,
preserveUserDefaults: true,
),
);| | With Confirmation | Show dialog before restart |
dart
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: true,
),
mode: RestartMode.withConfirmation,
dialogTitle: 'Restart Required',
dialogMessage: 'Do you want to restart?',
);| | After Update | Restart after applying updates |
dart
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: true,
clearData: false,
),
mode: RestartMode.withConfirmation,
dialogTitle: 'Update Ready',
dialogMessage: 'Restart to apply updates?',
);``` |
// Initialize with custom root reset handler
void main() {
WidgetsFlutterBinding.ensureInitialized();
TerminateRestart.instance.initialize(
onRootReset: () {
// Custom navigation reset logic
Navigator.of(context).pushNamedAndRemoveUntil('/home', (_) => false);
},
);
runApp(MyApp());
}
// Handle back navigation (Android)
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
// Your custom back navigation logic
return true;
},
child: Scaffold(
// Your app content
),
);
}
- Uses
Process.killProcess()
for clean termination - Handles activity recreation properly
- Manages app data clearing through proper Android APIs
- Supports custom intent flags
- Handles task stack management
- Implements clean process termination
- Handles UserDefaults and Keychain data preservation
- Manages view controller recreation for UI-only restarts
- Supports background task completion
- Handles state restoration
-
After Dynamic Updates
// After downloading new assets/code await TerminateRestart.instance.restartApp( options: const TerminateRestartOptions( terminate: true, ), mode: RestartMode.withConfirmation, dialogTitle: 'Update Ready', dialogMessage: 'Restart to apply updates?', );
-
Clearing Cache
// Clear app data but preserve important settings await TerminateRestart.instance.restartApp( options: const TerminateRestartOptions( terminate: true, clearData: true, preserveKeychain: true, preserveUserDefaults: true, ), );
-
Quick UI Refresh
// Refresh UI without full restart await TerminateRestart.instance.restartApp( options: const TerminateRestartOptions( terminate: false, ), );
-
With Confirmation Dialog
// Show confirmation dialog before restart await TerminateRestart.instance.restartApp( options: const TerminateRestartOptions( terminate: true, ), mode: RestartMode.withConfirmation, dialogTitle: 'Restart Required', dialogMessage: 'Do you want to restart the app?', confirmButtonText: 'Restart', cancelButtonText: 'Later', );
Operation | Average Time |
---|---|
UI-only Restart | ~300ms |
Full Termination | ~800ms |
Data Clearing | ~200ms |
With Dialog | +100ms |
-
Sensitive Data
- Use
preserveKeychain
for credentials - Clear data on logout
- Handle biometric authentication state
- Use
-
State Management
- Clear sensitive data before restart
- Implement proper authentication state handling
- Use secure storage for critical information
-
Platform Security
- Proper permission handling
- Secure data clearing
- Protected file access
Contributions are welcome! Here's how you can help:
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing
) - Commit your changes (
git commit -am 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Special thanks to:
- The Flutter team for the amazing framework
- All contributors who helped improve this plugin
- The community for valuable feedback and suggestions
If you have any questions or need help, you can:
- Open an issue
- Check our example for more usage examples
- Read our API documentation
Check out our example app for a full demonstration of all features, including:
- Basic UI/Process restart
- Data clearing with preservation options
- Custom confirmation dialogs
- Error handling
- State management
- Platform-specific features
The Android implementation uses a combination of techniques to ensure reliable app restart:
// Activity recreation (UI-only restart)
currentActivity.recreate()
// Full process termination
Process.killProcess(Process.myPid())
exitProcess(0)
// Smart Intent handling
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
The iOS implementation provides:
- Clean process termination
- State preservation options
- Keychain data handling
- User defaults management
Made with โค๏ธ by Ahmed Sleem GitHub โข pub.dev โข LinkedIn
Parameter | Type | Default | Description |
---|---|---|---|
terminate |
bool |
true |
Full termination vs UI-only restart |
clearData |
bool |
false |
Clear app data during restart |
preserveKeychain |
bool |
false |
Keep keychain data when clearing |
preserveUserDefaults |
bool |
false |
Keep user defaults when clearing |
-
UI-only Restart (~200ms):
- Maintains network connections
- Preserves background tasks
- Ideal for UI updates
-
Full Restart (~800ms):
- Terminates all processes
- Cleans up resources
- Required for security-related changes
class ThemeManager {
Future<void> toggleTheme() async {
// Update theme in your state management solution
// Example using Provider (implement based on your state management):
// Provider.of<ThemeProvider>(context, listen: false).toggleTheme();
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: false, // UI-only restart is sufficient
),
);
}
}
class UpdateManager {
Future<void> applyUpdate() async {
try {
// Show confirmation with custom message
final context = // Get valid context from your widget tree
final confirmed = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: Text('Update Ready'),
content: Text('Restart to apply updates?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: Text('Later'),
),
TextButton(
onPressed: () => Navigator.pop(context, true),
child: Text('Restart Now'),
),
],
),
);
if (confirmed == true) {
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: true, // Full restart for updates
clearData: false,
),
);
}
} catch (e) {
print('Update failed: $e');
}
}
}
// Initialize with custom navigation handling
TerminateRestart.instance.initialize(
onRootReset: () {
// Example: Reset to home screen and clear navigation stack
// Note: Ensure you have a valid context when accessing Navigator
Navigator.of(context).pushNamedAndRemoveUntil(
'/home',
(_) => false, // Remove all previous routes
);
},
);
- Complies with App Store guidelines regarding app termination
- Uses approved methods for activity recreation
- Handles state preservation according to iOS lifecycle
- Implements proper activity recreation
- Handles back navigation appropriately
- Manages process termination safely
-
Data Clearing
- Use
clearData: true
for security-sensitive operations - Enable
preserveKeychain
to retain critical credentials - Consider
preserveUserDefaults
for app settings
- Use
-
State Management
- Clear sensitive data before restart
- Implement proper authentication state handling
- Use secure storage for critical information
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
Special thanks to:
- Our beta testers and early adopters
- The Flutter community for valuable feedback
- Contributors who helped improve the package
This project is licensed under the MIT License - see the LICENSE file for details.
- UI-only Restart: Only recreates the UI components while keeping the app process alive. Perfect for theme changes or language switches.
- Full Restart: Completely terminates the app process and starts fresh. Ideal for updates or when you need a clean state.
Use confirmation dialog when:
- User needs to be aware of the restart
- Data might be lost during restart
- Action is user-initiated
- Critical operations are in progress
- By default, all app data is preserved
- Use
clearData: true
to clear app data - Use
preserveKeychain
andpreserveUserDefaults
to selectively preserve data
Yes! The plugin:
- Uses official platform APIs
- Follows platform guidelines
- Handles errors gracefully
- Has no special permission requirements
Future<void> changeLanguage(String newLocale) async {
// Save new locale
await prefs.setString('locale', newLocale);
// Restart UI only with confirmation
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: false,
preserveUserDefaults: true,
),
mode: RestartMode.withConfirmation,
dialogTitle: 'Language Change',
dialogMessage: 'Restart app to apply new language?',
);
}
Future<void> installUpdate() async {
try {
// Download update
await downloadUpdate();
// Apply update with confirmation
final confirmed = await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: true,
clearData: false,
preserveKeychain: true,
),
mode: RestartMode.withConfirmation,
dialogTitle: 'Update Ready',
dialogMessage: 'Install update and restart?',
);
if (!confirmed) {
scheduleUpdateReminder();
}
} catch (e) {
handleUpdateError(e);
}
}
Future<void> secureLogout() async {
// Clear sensitive data
await TerminateRestart.instance.restartApp(
options: const TerminateRestartOptions(
terminate: true,
clearData: true,
preserveUserDefaults: true, // Keep app settings
preserveKeychain: false, // Clear credentials
),
);
}
graph TD
A[Start] --> B{Restart Type}
B -->|UI-only| C[Recreation Mode]
B -->|Full| D[Termination Mode]
C --> E{Show Dialog?}
D --> E
E -->|Yes| F[Show Confirmation]
E -->|No| G[Process Restart]
F -->|Confirmed| G
F -->|Cancelled| H[Cancel Operation]
G --> I{Clear Data?}
I -->|Yes| J[Clear App Data]
I -->|No| K[Preserve Data]
J --> L[Restart App]
K --> L
L --> M[End]
-
Restart Type Selection:
- Choose between UI-only or Full restart
- Each type optimized for specific use cases
-
Confirmation Dialog (Optional):
- Can be added to any restart type
- Fully customizable UI
- User can cancel operation
-
Data Management:
- Optional data clearing
- Selective data preservation
- Secure handling of sensitive data
-
Platform-Specific Implementation:
- Android: Activity/Process management
- iOS: UIApplication handling
- Error handling and recovery