O armazenamento interno do aplicativo é um espaço dedicado no dispositivo acessível apenas a um aplicativo específico por meio de armazenamento isolado. De acordo com o Android Developers, 2026, cada aplicativo recebe seu próprio diretório sandbox ao qual outros aplicativos não têm acesso direto. Essa abordagem protege os dados contra leitura não autorizada e garante operação estável em um ambiente multitarefa de dispositivos móveis.
Principais pontos
Context.getFilesDir(), getCacheDir() e getDataDir() para acessar o armazenamento internoNSDocumentDirectory e NSCachesDirectory no contêiner Sandbox do aplicativoO armazenamento interno do aplicativo é um diretório isolado que o sistema operacional aloca para cada aplicativo durante a instalação. Outros aplicativos e o usuário não podem acessar este diretório através de gerenciadores de arquivos padrão. O sistema garante que todos os dados dentro deste diretório serão completamente excluídos quando o aplicativo for desinstalado. Essa abordagem constitui a base do modelo de segurança dos sistemas operacionais móveis, evitando vazamento de informações confidenciais entre programas.
Ao contrário do armazenamento externo (cartão SD), o armazenamento interno está sempre disponível e não requer verificação de presença de mídia. As velocidades de leitura e gravação na memória flash NAND de dispositivos modernos atingem 800–900 MB/s de leitura sequencial e 200–300 MB/s de gravação sequencial, comparáveis a SSDs SATA. O tamanho da área alocada depende da capacidade total do dispositivo e da política do fabricante: em dispositivos com 64 GB de memória flash, o aplicativo recebe de 16 a 64 MB de espaço inicial com possibilidade de expansão conforme necessário.
A arquitetura do armazenamento interno difere entre Android e iOS. No Android, cada aplicativo recebe um diretório /data/data/<package_name>/, dentro do qual o sistema cria subdiretórios files/, cache/ e databases/. No iOS, o aplicativo funciona em um contêiner Sandbox com os diretórios Documents/, Library/ e tmp/, cada um com sua própria finalidade e política de backup.
Os desenvolvedores têm acesso a vários métodos para salvar dados no armazenamento interno do aplicativo. Cada método resolve uma tarefa específica e é adequado para um tipo particular de dado. Escolher a abordagem correta afeta diretamente o desempenho do aplicativo, a facilidade de desenvolvimento e a segurança dos dados do usuário.
O método de nível mais baixo é a gravação direta de arquivos no diretório de arquivos. O aplicativo pode criar quaisquer arquivos e diretórios dentro de sua sandbox. Este método é adequado para armazenar arquivos de mídia, documentos do usuário e quaisquer dados binários que não exijam organização estruturada. No Android, o acesso ao diretório é feito através da chamada Context.getFilesDir(), que retorna o caminho absoluto para o diretório de arquivos do aplicativo. No iOS, a função NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) serve a um propósito semelhante.
Para armazenar pares chave-valor, o Android oferece SharedPreferences e o mais moderno DataStore baseado em corrotinas Kotlin e no protocolo protobuf. O SharedPreferences armazena dados em um arquivo XML dentro do diretório /data/data/<package>/shared_prefs/. Apesar da simplicidade de uso, o SharedPreferences tem desvantagens: a gravação síncrona pode causar atrasos na thread da UI, e a falta de segurança de tipos aumenta o risco de erros. O DataStore resolve esses problemas fornecendo uma API assíncrona baseada em Flow e suporte completo a tipos através de esquemas protobuf.
Para dados estruturados com conexões relacionais, a escolha ideal é SQLite ou o wrapper Room. O banco de dados é armazenado em um único arquivo dentro do diretório databases/ e suporta sintaxe SQL completa. O Room é uma biblioteca oficial do Jetpack que fornece uma API type-safe, migração automática de esquema e suporte a corrotinas. O tamanho do banco de dados pode atingir vários gigabytes sem perda significativa de desempenho com indexação adequada. O SQLite em dispositivos móveis lida com até 50.000 operações de gravação por segundo em um processador flagship moderno.
Para armazenar dados confidenciais como tokens de autenticação e chaves de criptografia, o Android fornece o EncryptedSharedPreferences. Este wrapper sobre o SharedPreferences padrão criptografa automaticamente chaves e valores usando AES256-GCM-None. A criptografia é realizada no nível do arquivo antes de gravar no disco, portanto, mesmo com acesso físico ao dispositivo, um invasor não pode ler o conteúdo. O EncryptedSharedPreferences faz parte da biblioteca AndroidX Security, que também inclui o EncryptedFile para criptografar arquivos inteiros.
O Android SDK fornece um conjunto de métodos para trabalhar com armazenamento interno através da classe Context. Cada método retorna um caminho para um diretório específico do sistema dentro da sandbox do aplicativo. Vamos examinar as operações básicas de gravação e leitura de arquivos usando Kotlin como exemplo.
O método principal para obter o caminho para o diretório de arquivos interno é context.filesDir. Ele retorna um objeto File apontando para o diretório /data/data/<package>/files/. No primeiro acesso, o sistema cria automaticamente todos os diretórios pais necessários. O tamanho dos arquivos no armazenamento interno não é explicitamente limitado, mas o volume total de dados não deve exceder o espaço disponível na partição /data, que geralmente representa 60–80% da capacidade total da memória flash.
val context = getApplicationContext()
val file = File(context.filesDir, "notes.txt")
file.writeText("Conteúdo da nota")
val content = file.readText()
println("Lido: $content")
Os métodos writeText e readText são funções de extensão da biblioteca padrão do Kotlin. Eles gerenciam automaticamente a abertura e fechamento de fluxos, evitando vazamentos de memória. Para dados binários, use writeBytes e readBytes, que não requerem codificação e trabalham com arrays ByteArray. Ao trabalhar com arquivos grandes, recomenda-se usar fluxos bufferizados: BufferedReader e BufferedWriter para texto, BufferedInputStream e BufferedOutputStream para dados binários.
Para organizar arquivos em uma hierarquia, crie subdiretórios dentro de filesDir. Isso ajuda a estruturar dados por tipo: imagens, documentos, arquivos de exportação. O método mkdirs() cria todos os diretórios ausentes no caminho, incluindo os aninhados. Certifique-se de que a operação de criação foi bem-sucedida — o método retorna true apenas quando novos diretórios são criados. Falhas de criação geralmente estão relacionadas a espaço insuficiente na partição /data ou esgotamento de inodes do sistema de arquivos.
val imagesDir = File(context.filesDir, "images")
if (imagesDir.mkdirs()) {
println("Diretório criado")
}
val imageFile = File(imagesDir, "photo.jpg")
imageFile.writeBytes(byteArray)
Para verificar o espaço disponível antes de gravar arquivos grandes, use File.getFreeSpace() ou File.getUsableSpace(). O segundo método retorna o número de bytes disponíveis para o aplicativo atual considerando cotas de segurança — é mais preciso no contexto de dispositivos multiusuário. Se o espaço disponível for menor que o tamanho esperado do arquivo, mostre uma mensagem ao usuário e sugira liberar espaço nas configurações do dispositivo.
No iOS, cada aplicativo funciona em um contêiner Sandbox isolado. O sistema não fornece uma API para sair de seus limites sem entitlements especiais. A principal ferramenta para trabalhar com o sistema de arquivos é a classe FileManager do framework Foundation. O contêiner Sandbox inclui vários diretórios padrão, cada um com sua própria política de backup.
O diretório Documents é destinado a dados do usuário que devem persistir entre as inicializações do aplicativo e ser restaurados a partir do backup. O iOS inclui automaticamente este diretório nos backups do iCloud e iTunes. O método urls(for:in:) retorna um array de URLs do diretório solicitado — o primeiro elemento do array é o principal.
let fm = FileManager.default
let docs = fm.urls(
for: .documentDirectory,
in: .userDomainMask
).first!
let fileURL = docs.appendingPathComponent("data.plist")
try data.write(to: fileURL)
O FileManager suporta um conjunto completo de operações de arquivo: criar, copiar, mover, excluir e renomear arquivos. Cada operação pode lançar um erro, portanto, todas as chamadas devem ser envolvidas em uma construção do-catch. Preste atenção especial à exclusão de arquivos — a operação é irreversível e restaurar dados após removeItem(at:) é impossível sem um backup prévio.
Nem todos os dados no contêiner Sandbox devem ser incluídos no backup do iCloud. Por exemplo, imagens em cache baixadas ou arquivos temporários de processamento não precisam ser restaurados — eles serão recriados no próximo uso. Para excluir um diretório ou arquivo do backup, defina o atributo isExcludedFromBackup como true. A Apple recomenda sempre excluir do backup dados que podem ser restaurados remotamente, para minimizar o uso do armazenamento do iCloud e reduzir o tempo de recuperação.
var cacheURL = fm.urls(
for: .cachesDirectory,
in: .userDomainMask
).first!
cacheURL.hasExcludedFromBackupKey = true
var values = URLResourceValues()
values.isExcludedFromBackup = true
try cacheURL.setResourceValues(values)
Cada tipo de armazenamento em um dispositivo móvel tem seu propósito e regras de uso. Compreender essas diferenças ajuda o desenvolvedor a escolher o local correto para cada tipo de dado. Abaixo está uma comparação dos três principais tipos de armazenamento disponíveis para um aplicativo.
| Característica | Internal Storage | Diretório Cache | External Storage |
|---|---|---|---|
| Visibilidade para outros apps | Oculta | Oculta | Acessível |
| Exclusão ao desinstalar o app | Completa | Completa | Depende da localização |
| Backup | Android — não, iOS — sim (Documents) | Não | Apenas ao sincronizar |
| Disponibilidade sem mídia | Sempre | Sempre | Requer cartão SD |
| Risco de perda de dados | Mínimo | Alto | Médio |
| Tamanho de arquivo recomendado | Até 100 MB | Até 50 MB | Qualquer |
O armazenamento interno é ideal para armazenar configurações do aplicativo, arquivos de banco de dados e documentos do usuário que não devem estar acessíveis a outros programas. O diretório de cache é destinado a arquivos temporários que podem ser recriados no próximo uso: imagens baixadas, respostas de API, dados intermediários de processamento. O armazenamento externo é mais adequado para arquivos de mídia grandes (fotos, vídeos, música) e dados que o usuário deseja compartilhar com outros aplicativos através de acesso compartilhado.
Escolher o tipo de armazenamento também afeta a classificação do aplicativo na Google Play e App Store. Aplicativos que armazenam grandes volumes de dados no armazenamento interno sem limpeza recebem avaliações negativas: os usuários reclamam da falta de espaço. De acordo com um estudo da App Annie, 62% dos usuários excluem um aplicativo se ele ocupar mais de 500 MB de armazenamento interno do dispositivo sem opção de limpeza.
O gerenciamento adequado do armazenamento interno do aplicativo melhora o desempenho, a segurança e a experiência do usuário. As seguintes recomendações são baseadas na documentação oficial do Android e iOS, bem como na experiência prática de desenvolvimento de aplicativos com milhões de instalações.
Atenção especial deve ser dada aos testes de casos limite. Verifique o comportamento do aplicativo quando o armazenamento interno está cheio, quando uma operação de gravação é interrompida inesperadamente (falha do aplicativo, chamada recebida) e ao restaurar a partir de um backup do iOS. Em cada um desses cenários, os dados devem permanecer consistentes ou ser restaurados ao último estado estável. Use arquivos transacionais: grave dados em um arquivo temporário e, em seguida, renomeie-o atomicamente para o destino. Isso evita a leitura de dados corrompidos em caso de falha de gravação.
Não se esqueça do controle do usuário. Forneça nas configurações do aplicativo uma opção para limpar dados temporários e exibir o volume ocupado do armazenamento interno. De acordo com o Google Play Console, aplicativos com esse recurso recebem 18% mais avaliações positivas na categoria «Desempenho».
Perguntas frequentes
Todos os dados do armazenamento interno do aplicativo são completamente excluídos. O sistema operacional garante a ausência de arquivos residuais, incluindo bancos de dados, configurações e arquivos temporários. Os dados no armazenamento externo podem persistir.
Sem acesso root ao dispositivo, outros aplicativos não podem ler arquivos do Internal Storage de outro aplicativo. No Android, isso requer privilégios de superusuário, enquanto no iOS, o isolamento é aplicado no nível do kernel através do Sandbox.
Não há limite explícito, mas o volume total é restrito pelo espaço disponível na partição /data. Recomenda-se não exceder 100 MB por aplicativo — volumes maiores devem ser colocados em armazenamento externo ou na nuvem.
filesDir é destinado a dados permanentes do aplicativo e o sistema não o exclui a menos que necessário. cacheDir é para arquivos temporários que o sistema pode excluir quando a memória está baixa. O sistema não garante a persistência do cacheDir.
A cópia direta do Internal Storage para um cartão SD é proibida pela política de segurança. Use a API MediaStore no Android 10+ ou SAF (Storage Access Framework) para criar cópias de dados no armazenamento compartilhado com o consentimento do usuário.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também