How to delete all the boxes in the hive in flutter? - flutter

I am using Hive to store the data locally, but the boxes are created dynamically throughout the apps and don't know how many boxes are there in total.
I want to delete all the boxes, whether open or closed, when the user presses the reset button.
So far, I could delete all open boxes or the particular box but not all.
Is there is a way to do that? Or is there any way to open all the boxes at once?

If you want to close all open boxes
Hive.close();
If you want to delete all currently open boxes from disk
Hive.deleteFromDisk();

I created this extension:
import 'dart:async';
import 'dart:io';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
extension on HiveInterface {
/// Get a name list of existing boxes
FutureOr<List<String>> getNamesOfBoxes() async {
final appDir = await getApplicationDocumentsDirectory();
var files = appDir.listSync();
var _list = <String>[];
files.forEach((file) {
if (file.statSync().type == FileSystemEntityType.file
&& p.extension(file.path).toLowerCase() == '.hive') {
_list.add(p.basenameWithoutExtension(file.path));
}
});
print('Current boxes: $_list');
return _list;
}
/* ---------------------------------------------------------------------------- */
/// Delete existing boxes from disk
void deleteBoxes() async {
final _boxes = await this.getNamesOfBoxes();
if (_boxes.isNotEmpty) _boxes.forEach((name) => this.deleteBoxFromDisk(name));
}
}

As of now, I have to keep track of the boxes by again creating the box to store all the box information, and delete the box by reading the number of boxes stored and then resetting the box info also.

Related

Create a box from a flutter .hive file stored in the cache

I know this may sound simple but I have a hive file (which I got from the File Picker package) and now, based on this hive file, I want to load the Box. Is there an easy way to just load the box from the hive file? Something like:
Box newBox= await Hive.openBox('boxName', path: hiveFile.path)
First, you need to open your new Hive box:
final box = await Hive.openBox<T>("boxExmapleName");
This box now will have its own file saved locally, and until now it's empty, right, we can get it's path with:
final boxPath = box.path;
Now, after we had its path, we need to close that box, so we can make changes to its file properly:
await box.close();
Until this, we have the box path, and it's closed, then we can copy set our personnel Hive box file into that box that we just created:
File("HERE THE PATH OF THE PERSONNEL HIVE BOX").copy(boxPath);
Change "HERE THE PATH OF THE PERSONNEL HIVE BOX" with the path of your hive file.
This will copy that file into the created box file.
so combining it as a method:
Future<void> HiveBoxFromFile<T>(String boxName, String PathOfFile) async {
final box = await Hive.openBox<T>(boxName);
final boxPath = box.path;
await box.close();
try {
File(PathOfFile).copy(boxPath);
} finally {
await Hive.openBox<T>(boxName); // this is to re-open the box again after the operation is finished
}
}
Now you should use the box in your app, and it will have the data that was in the file.

Flutter web: Store a CSV file to Firebase Storage without uploading it from the computer

I'm trying to transform a Flutter mobile application into to a Flutter web application. In the Flutter application I generated a csv file, stored it in the memory of the phone and then uploaded it to Firebase storage, here is a snippet of the relevant code:
//relevant imports:
import 'dart:io';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:path_provider/path_provider.dart' as path_provider;
import 'package:csv/csv.dart';
//relevant code
Future writeCSV(..) async{
final _storage = FirebaseStorage.instance;
List<List> names = [];
//...
//Store data in the list 'names'
//....
final directory = await path_provider.getExternalStorageDirectory();
File file = await File('${directory.path}/data.csv').create();
String csv = const ListToCsvConverter().convert(names);
await file.writeAsString(csv);
var snapshot = await _storage.ref().child('data2.csv').putFile(file).onComplete;
}
How could one go about this in Flutter web? When I tried to search for solutions, I could only find examples where you uploaded the file from the computer, but I would like to generate the file directly and then upload it to Firebase storage
I was able to do this in the following manner:
import 'dart:html';
import 'package:firebase/firebase.dart' as fb;
//..
//..
String data = 'name,city,age\nSimon,London,30\nJohn,New York,40';
final path = 'data.csv';
var file_contents = <String>[data];
var blob = Blob(file_contents, 'text/csv', 'native');
fb.storage().refFromURL('gs://<name>.appspot.com/')
.child(path).put(blob);

How to get random photos from gallery without picker Flutter?

I need to extract some random images from gallery without the picker option. Please be clear that I don't want to open picker for this, just extract images if user tapped the button.
You could use dart:io to get the files in a directory and display one of the image files in the directory.
import 'dart:io' as io;
var files = io.Directory("/storage/emulated/0/DCIM/Camera").listSync();
final _random = new math.Random();
var idx= _random.nextInt(files.length) ;
var file = files[idx];
//TODO display the file.

How to find memory leaks in Flutter?

I need to find memory leaks in Flutter.
How to find them? and how to create memory leaks for the test?
I am implemented Memory leak testing in android studio ide.
Step - 1 :
Connect your device with android studio and run your application on your device.
Step - 2 :
Go to View -> Tool Windows -> Flutter Performance
Step - 3 :
Bottom of the window Open Dev Tools option will be there, click on it. It will be navigate into new window of your browser.
See below image for more details :
Step - 4 :
To follow the steps below as per the screenshot, you can see the size and details of the object causing the memory leak.
First Select Memory from available menus than you can able to see below ui.
first: Click on settings icon
then: Mark down Dart and Flutter checkboxes.
and finally: Click on Apply button.
Step - 5 :
This is final step, now you can able to see memory leaking info.
first: Click on Snapshot it will be collect and display object list in bottom of the window.
and then: Click on search icon and Here you can see those classes which objects are not destroyed. Suppose am selected ApiRepository.dart class and instance will be available in memory ,so that details are visible in window. If multiple objects created than you can see here the total no. of instance and total size.
Step - 6 :
You can able to call Garbage Collector manually by using GC icon . You can anytime Reset and get latest snapshot using Reset and Snapshot buttons.
For more information about Memory allocation related details read below articles :
Offical document about memory leak on flutter.dev
Article about garbage collector.
You can start from reading the official documentation - https://docs.flutter.dev/development/tools/devtools/memory
The next steps describe how to run the Memory view and how to create memory leaks manually:
Press the "Open Flutter DevTools" button. It opens browser. In my case it's Safari (on Mac). If you see just a white screen, copy the link and paste it to Chrome.
Select the "Memory" tab.
Press on the graph. You will see a lot of values for the selected period of time. Take a look at "Dart/Flutter" memory usage. In my case it's 50.52 MB
You can simulate significant amount of leaks using the next code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class MemoryLeakObject {
final String text;
MemoryLeakObject(this.text);
}
List<MemoryLeakObject> leakObjects = [];
class MemoryLeaksScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: CupertinoButton(
child: const Text(
'Create 1 000 000 leaks',
),
onPressed: () {
while (leakObjects.length < 1000000) {
leakObjects.add(
MemoryLeakObject('Count: ${leakObjects.length}'),
);
}
},
),
),
);
}
}
Open the screen with the code above and press the 'Create 1 000 000 leaks' button.
Take a look at the graph again. In my case the "Dart/Flutter" memory usage increased to 101.28 MB. Also a Snapshot was created with all the objects in the memory. As you can see, there are 933365 objects of the "MemoryLeakObject" class.
If you want/need to add non-integration tests to reproduce/fix the memory leak, here is the approach. In short, it runs on your host by simply flutter test, and does not depend on a simulator/real-device at all.
Example usage: https://gist.github.com/fzyzcjy/e68c375643d7c77942cdc8fb5f01de18
Code (without example):
import 'dart:async';
import 'dart:developer';
import 'dart:io';
import 'dart:isolate';
import 'package:common_dart/utils/processes.dart';
import 'package:front_log/front_log.dart';
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart' hide Isolate, Log;
import 'package:vm_service/vm_service.dart' as vm_service;
import 'package:vm_service/vm_service_io.dart';
const _kTag = 'vm_services';
// #4657
FutureOr<void> runTestsInVmService(
FutureOr<void> Function(VmServiceUtil) body, {
required String selfFilePath,
}) async {
Log.d(_kTag, 'runInVmService selfFilePath=$selfFilePath Platform.script.path=${Platform.script.path}');
if (Platform.script.path == selfFilePath) {
final vmService = await VmServiceUtil.create();
tearDownAll(vmService.dispose);
await body(vmService);
} else {
test(
'run all tests in subprocess',
// #4764
timeout: const Timeout(Duration(seconds: 60)),
() async {
await executeProcess('dart', ['run', '--enable-vm-service', selfFilePath]);
},
);
}
}
/// https://stackoverflow.com/questions/63730179/can-we-force-the-dart-garbage-collector
class VmServiceUtil {
static const _kTag = 'VmServiceUtil';
final VmService vmService;
VmServiceUtil._(this.vmService);
static Future<VmServiceUtil> create() async {
final serverUri = (await Service.getInfo()).serverUri;
if (serverUri == null) {
throw Exception('Cannot find serverUri for VmService. '
'Ensure you run like `dart run --enable-vm-service path/to/your/file.dart`');
}
final vmService = await vmServiceConnectUri(_toWebSocket(serverUri), log: _Log());
return VmServiceUtil._(vmService);
}
void dispose() {
vmService.dispose();
}
Future<void> gc() async {
final isolateId = Service.getIsolateID(Isolate.current)!;
final profile = await vmService.getAllocationProfile(isolateId, gc: true);
Log.d(_kTag, 'gc triggered (heapUsage=${profile.memoryUsage?.heapUsage})');
}
}
String _toWebSocket(Uri uri) {
final pathSegments = [...uri.pathSegments.where((s) => s.isNotEmpty), 'ws'];
return uri.replace(scheme: 'ws', pathSegments: pathSegments).toString();
}
class _Log extends vm_service.Log {
#override
void warning(String message) => Log.w(_kTag, message);
#override
void severe(String message) => Log.e(_kTag, message);
}

How to fix Flutter stream exiting whenever i try to listen to it

In a flutter app, I'm trying to read a large csv file one line at a time by opening a stream on it. The issue is that when i try to listen to the stream the execution just skips over that code block and the program ends.
The file I'm opening is located in my assets folder and I've confirmed programmatically that it does exist before opening the stream. Changing the file the stream is opened on doesn't help, the same problem persists. I've also tried to change the way i listen to the stream, following different methods provided by Darts official documentation (that code is commented out) but the outcome is again the same. The assets have been declared in the pubspec.yaml. When i change the code to read the file as a String the program works perfectly but I want to use a stream because the file is so massive that creating a String object for it would take a large amount of time and memory.
void trainDigitsStream() async{
List<List<List>> filters = createRandomFilter(4, 4, 1, -1, 1);
List flattened= new List<double>();
File file = new File("assets/digit_train_data.csv");
if(file.existsSync())print("EXISTS!");
Stream<List<int>> stream = file.openRead();
Stream lines = utf8.decoder.bind(stream).transform(LineSplitter());
/*
try{
await for (var line in lines){
print(line);
}
print("file ended");
}catch(e){
print(e);
}
*/
lines.listen((data){//code exits here, execution never reaches next line
String line = data.toString();
List<List> instance = new List<List<int>>();
List x = new List<int>();
int i = 0;
line.split(',').forEach((d){
x.add(int.parse(d));
i++;
if(i == 28){
instance.add(x);
x = new List<int>();
i = 0;
}
});
List<List<List>> kernels = new List<List<List<double>>>();
List<List> pools = new List<List>();
filters.forEach((f){kernels.add(convo.applyFilter(instance, f, 0));});
kernels.forEach((k){pools.add(pool.maxPool(k, 2));});
pools.forEach((p){flattened.addAll(p);});
});
}
It's hard without further information, It would be better if you can post more information.
So I guess the problem should be , please check the following two steps.
1. Register the assets folder in pubspec.yaml
flutter:
assets:
- assets/digit_train_data.csv
2. You need to use rootBundle to access this csv file, reference document https://flutter.dev/docs/development/ui/assets-and-images
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
Future<String> loadAsset() async {
return await rootBundle.loadString('assets/digit_train_data.csv');
}
similar question here Flutter - Read text file from assets