Hive — lätt NoSQL-lager för Flutter som fungerar utan native-kod. Till skillnad från SQLite eller Firebase kräver Hive inte anslutning av native-bibliotek och fungerar uteslutande genom Dart. Enligt Pub.dev, 2024 har Hive laddats ner över 10 miljoner gånger och används i vart tredje Flutter-projekt som kräver lokal datalagring utan serverinfrastruktur.
Huvudpunkter
Hive — är en NoSQL-databas skriven helt i Dart som inte kräver native-bibliotek. Den skapades av Simon Leiter 2019 som ett alternativ till SQLite för Flutter-projekt. Hive lagrar data i binärt .hive-format, som är optimerat för snabb läsning och skrivning på mobila enheter. .hive-formatet använder ett anpassat serialiseringsschema där varje datatyp har sitt eget byteprefix, vilket gör att filen kan läsas utan förkunskaper om schemat — till skillnad från Protocol Buffers eller FlatBuffers.
Huvudidén med Hive — maximal enkelhet. Databasen kräver inte initiering av native-motorer, innehåller ingen SQL-parser och använder inte reflektion. Alla operationer är direkta anrop av Dart-funktioner med binär serialisering via WriteBuffer och ReadBuffer.
Enligt en undersökning av Flutter Community (2023) är Hive bland de 5 mest använda paketen för datalagring i Flutter, näst efter shared_preferences i popularitet, men överträffar det i funktionalitet och hastighet.
Hive använder konceptet Box — motsvarigheten till en tabell i relationsdatabaser. Varje Box är en fil på disken med en uppsättning nyckel-värdepar. Nyckeln kan vara int eller String, värdet — vilken primitiv typ som helst, lista, Map eller anpassat objekt via TypeAdapter. Boxar är isolerade från varandra och öppnas oberoende.
Hive kräver inte plattformskanaler (platform channels). Det betyder att det fungerar likadant på Android, iOS, Web, macOS, Windows och Linux utan extra konfiguration. För projekt som riktar in sig på webbkompilering är Hive den enda lätta NoSQL-lösningen — SQLite fungerar inte i webbläsaren. Samtidigt använder Hive IndexedDB som backend för webben, vilket garanterar datapersistens även i webbläsarmiljön.
Hive serialiserar data till binärt format vid skrivning och deserialiserar vid läsning. Den interna mekanismen är baserad på BinaryWriter och BinaryReader, som packar data i kompakta byte-arrayer. Lagringsstorleken på disken är i genomsnitt 2–3 gånger mindre än JSON-representationen av samma data.
När en Box öppnas laddar Hive hela filen i RAM-minnet. Detta ger hög läshastighet (mikrosekunder), men lägger en begränsning på datastorleken: det rekommenderas att lagra högst 50–100 MB per Box. För större volymer, använd LazyBox — lat laddning av poster från disken.
Hive fungerar entrådigt i isoleringen av Dart-isolat. Skrivoperationer utförs synkront med fillåsning. För asynkron åtkomst, använd Hive.openBox() med await. Konkurrerande åtkomst från flera isolat stöds inte direkt — för detta behövs en separat synkroniseringsmekanism.
Hive befinner sig i en nisch mellan SharedPreferences och SQLite. Det är mer komplext än SharedPreferences (stöder anpassade objekt), men enklare än SQLite (kräver inga SQL-frågor). Låt oss jämföra nyckelegenskaperna.
| Egenskap | Hive | SharedPreferences | SQLite |
|---|---|---|---|
| Datatyper | Alla (via TypeAdapter) | Endast primitiver | SQL-typer |
| Läshastighet | ~30 000 ops/s | ~5 000 ops/s | ~2 000 ops/s |
| Native-kod | Krävs inte | Krävs (Android) | Krävs |
| Webbstöd | Ja | Nej | Nej |
| Komplexitet | Låg | Minimal | Medel |
| Reaktivitet | WatchBox | Nej | Via ORM |
Hive är optimalt för små datamängder: appinställningar, cache för API-svar, lokal synkroniseringskö, favoriter och webbhistorik. Om data inte överstiger 50 MB och inte kräver relationsfrågor — är Hive snabbare och enklare än SQLite.
Hive stöder inte frågor med filtrering på flera fält, JOIN, aggregeringsfunktioner. Om du behöver komplexa frågor som “välj alla uppgifter för idag med prioritet över 3” — använd SQLite med drift eller floor. Hive är inte heller lämpligt för lagring av mer än 100 MB data på grund av inläsning i minnet.
Hive börjar med initiering och öppning av en Box. Nedan visas grundläggande operationer för ett typiskt scenario — lagring av en uppgiftslista i en Flutter-app. Alla exempel fungerar utan native-plattformsanrop.
Innan du använder Hive måste Hive.initFlutter() anropas i main-funktionen. Öppna sedan Box via Hive.openBox() — resultatet blir en Box-instans redo för läsning och skrivning.
import 'package:hive/hive.dart';
import 'package:hive_flutter/hive_flutter.dart';
void async main() {
await Hive.initFlutter();
final settingsBox = await Hive.openBox('settings');
runApp(MyApp());
}
Box tillhandahåller metoderna put, get, delete och innehåller en iterator för att gå igenom alla poster. Nycklar och värden typas via generics — som standard tillåter Box<dynamic> alla typer, men det rekommenderas att ange en specifik typ.
// Skriva data
final box = await Hive.openBox<String>('tasks');
await box.put('task_1', 'Köp produkter');
// Läsa
final task = box.get('task_1');
// Alla nycklar
final allTasks = box.values.toList();
// Radera
await box.delete('task_1');
// Rensa Box
await box.clear();
WatchBox — en utökning av Box som meddelar prenumeranter om ändringar. I Flutter integreras detta med ValueListenableBuilder: när ett värde i Box ändras återuppbyggs widgeten automatiskt utan att anropa setState.
final watchBox = await Hive.openBox('settings');
// I widget
ValueListenableBuilder(
valueListenable: watchBox.listenable(),
builder: (context, box, _) {
final counter = box.get('counter') ?? 0;
return Text('Räknare: $counter');
},
)
TypeAdapter — Hives mekanism för serialisering av anpassade Dart-objekt. Adaptern beskriver hur ett objekt konverteras till binärt format (write) och tillbaka (read). Till skillnad från json_serializable kräver TypeAdapter ingen reflektion och fungerar snabbare.
Adaptern implementerar gränssnittet TypeAdapter
// Datamodell
class Task {
final String title;
final bool isCompleted;
Task({required this.title, this.isCompleted = false});
}
// TypeAdapter
class TaskAdapter extends TypeAdapter<Task> {
@override
final int typeId = 0;
@override
Task read(BinaryReader reader) {
return Task(
title: reader.readString(),
isCompleted: reader.readBool(),
);
}
@override
void write(BinaryWriter writer, Task obj) {
writer.writeString(obj.title);
writer.writeBool(obj.isCompleted);
}
}
För projekt med många modeller tillhandahåller Hive hive_generator och build_runner. Annotationen @HiveType på klassen och @HiveField på fält genererar adaptern automatiskt. Detta är praktiskt när modellen innehåller 10+ fält — manuell skrivning av read/write blir tidskrävande.
Hive utför läsning från minnet, inte från disken, vilket ger hastighet upp till 30 000 operationer per sekund. För optimering: öppna Box en gång och återanvänd den i hela appen, anropa inte openBox igen. Använd Hive.box() (synkron getter) efter initiering — returnerar en redan öppnad Box utan att skapa en ny instans.
Hive integreras enkelt med populära Flutter-state managers. För Provider, använd ChangeNotifierProvider som läser data från Box vid initiering och uppdateras via listenable. För Riverpod passar StreamProvider som prenumererar på WatchBox. En sådan kombination ger reaktiva UI-uppdateringar vid varje dataändring i Hive utan manuellt setState-anrop. I ett typiskt Flutter-projekt möjliggör sådan arkitektur synkronisering av tillstånd mellan skärmar utan global singleton.
Vanliga frågor
Hive fungerar i ren Dart, så det kan användas i vilket Dart-projekt som helst: server (Dart VM), konsol eller AngularDart. För Flutter ansluts dessutom hive_flutter med initiering av lagringsvägar.
Hive stöder AES-256-kryptering via parametern encryptionKey när Box öppnas. Nyckeln måste vara en 32-byte-sträng. Krypterad Box kan inte läsas utan nyckeln — data skyddas på filnivå.
Isar — efterträdaren till Hive från samma författare (Simon Leiter). Isar är snabbare, stöder index, relationer och komplexa frågor. Hive förblir dock relevant för enkla scenarier där Isars relationskapacitet inte behövs och för projekt där minimalt beroende är viktigt.
Hive har ingen inbyggd migrering. Om TypeAdapter-strukturen har ändrats kommer gamla data inte att deserialiseras. Lösning: öka adapterens typeId och skriv en manuell migrering i koden, eller använd delete för den gamla nyckeln innan du skriver en ny.
Hive laddar Box helt i minnet. Rekommenderad gräns är 50–100 MB per Box. Vid överskridande kan förseningar uppstå vid öppning av Box och ökad RAM-förbrukning. För större volymer, använd flera Boxar eller LazyBox med lat laddning.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också