Untuk semua orang yang, terlepas dari segalanya, berhasil membuat pilihan yang tepat.
Ini adalah terjemahan dari serangkaian artikel dari Mark Murphy dari CommonsWare, yang dikenal luas di stackoverflow, serta penulis buku "Panduan Sibuk untuk Pengembangan Android", "Komponen Arsitektur Android". Beberapa istilah tidak diterjemahkan secara khusus.
Penyimpanan internal
Ada banyak kebingungan mengenai model penyimpanan Android. Kebingungan telah tumbuh secara signifikan dengan perubahan Android 4.4 di Storage Model, dan sejak itu situasinya belum membaik. Ada banyak pertanyaan tentang Stack Overflow dan sumber daya serupa, di mana orang jelas tidak sepenuhnya berpengalaman dalam berbagai model penyimpanan Android.
Apa yang pengguna anggap sebagai Penyimpanan Internal
Tergantung pada model perangkat Anda, pengguna pada akhirnya akan datang ke Pengaturan -> Penyimpanan di perangkat mereka atau lokasi yang setara, dan dapat melihat layar yang menggambarkan "Penyimpanan internal" .
Pengguna berpikir bahwa seluruh flash drive internal adalah "Penyimpanan Internal". Untungnya, Google mulai mengubah istilah ini dengan Android 8.0, pindah ke "penyimpanan umum" alih-alih "penyimpanan internal".
Namun, pengguna masih dapat melihat "penyimpanan internal" di tempat-tempat seperti jendela Windows Explorer ketika perangkat mereka terhubung melalui USB.
Apa Google Mempertimbangkan Penyimpanan Internal
Sayangnya, apa yang dilihat pengguna tidak sama dengan apa yang dianggap Android SDK sebagai "penyimpanan internal", yang menyebabkan beberapa kebingungan. Jika Anda membaca dokumentasi Android pada repositori internal , maka deskripsi ini ... setidaknya berkabut (teks telah berubah sejak saat penulisan):
Anda dapat menyimpan file secara langsung ke memori internal perangkat. Secara default, file yang disimpan dalam penyimpanan internal bersifat pribadi untuk aplikasi Anda, dan aplikasi lain tidak dapat mengaksesnya (serta pengguna). Saat pengguna mencopot pemasangan aplikasi, file-file ini dihapus.
Sebenarnya, Android SDK mendefinisikan "penyimpanan internal" sebagai direktori khusus untuk aplikasi Anda, tempat aplikasi Anda dapat meng-host file. Seperti yang disarankan dalam dokumentasi, file-file ini dimaksudkan untuk membaca dan menulis ke aplikasi Anda secara default dan dilarang untuk aplikasi lain (pengecualian: pengguna yang bekerja dengan manajer file dengan hak pengguna super pada perangkat yang di-root dapat mengakses semuanya).
Konteks memiliki beberapa metode dasar yang memberi Anda akses ke penyimpanan internal, termasuk:
getCacheDir()
getDir()
getDatabasePath()
getFilesDir()
openFileInput()
openFileOutput()
Metode lain akan bergantung pada mereka, seperti openOrCreateDatabase()
. Kelas-kelas lain juga akan bergantung pada mereka, seperti SQLiteOpenHelper
dan SharedPreferences
.
Di mana Penyimpanan Internal disimpan ... Terkadang
Jika Anda melihat berbagai posting blog, respons StackOverflow, dan buku-buku yang dirilis pada 2012 atau sebelumnya, Anda diberitahu bahwa "penyimpanan internal" aplikasi Anda berada di / /data/data/your.application.package.name
. /data/data/your.application.package.name
. /data/data/your.application.package.name
. /data/data/your.application.package.name
.
Di dalamnya akan ada beberapa direktori yang secara otomatis dibuat oleh Android, saat Anda menggunakan beberapa metode Konteks. Sebagai contoh, getFilesDir()
mengembalikan objek File
menunjuk ke files/
direktori di penyimpanan internal aplikasi Anda.
Di mana Penyimpanan Internal disimpan ... Sisa waktu
Namun, penyimpanan internal aplikasi Anda tidak selalu di lokasi yang ditentukan. Untuk pengembang, ada satu aturan yang harus Anda pelajari dari serangkaian posting blog ini:
JANGAN PERNAH HARDCODE PATHS .
Dari waktu ke waktu, saya melihat pengembang melakukan hal seperti ini:
File f=new File("/data/data/their.app.package.name/files/foo.txt");
Ini bukan kejahatan, ini lebih buruk, ini adalah kesalahan.
Langkah yang benar, dan kurang menulis:
File f=new File(getFilesDir(), "foo.txt");
Lebih penting lagi, penyimpanan internal tidak selalu di tempat yang sama . Perlu dicatat bahwa kami memiliki konsep profil pengguna yang terpisah (profil pengguna terpisah), dimulai dengan Android 4.2 untuk tablet dan Android 5.0 untuk ponsel. Setiap pengguna mendapatkan "penyimpanan internal" mereka sendiri. Meskipun direktori di atas masih digunakan untuk pengguna utama, itu tidak dijamin bahwa itu akan digunakan untuk akun sekunder.
Menjelajahi Penyimpanan Internal
Alat Device File Explorer di Android Studio 3.0+ dapat melihat semua penyimpanan internal pada emulator, serta penyimpanan internal aplikasi yang di-debug pada perangkat produksi.
Di baris perintah, Anda dapat menggunakan adb
dengan opsi run-as
.
Misalnya, untuk mengunggah database dari penyimpanan internal pengguna utama ke mesin pengembangan Anda, Anda dapat menggunakan:
adb shell 'run-as your.application.package.name cp /data/data/your.application.package.name/databases/dbname.db /sdcard'
Harap dicatat bahwa:
- Anda perlu mengubah tujuan ke tempat penyimpanan eksternal dipasang pada perangkat Anda (ditampilkan di sini sebagai
/sdcard/
, yang tidak akan sama pada semua perangkat) - Anda mungkin perlu menggunakan
cat
alih-alih cp
pada perangkat yang lebih lama - Setelah file terletak di penyimpanan eksternal, Anda dapat menggunakan
adb pull
untuk mengunduhnya ke komputer Anda, atau mengaksesnya dengan cara biasa lainnya (misalnya, dengan memasang perangkat sebagai disk).
Keterbatasan Penyimpanan Internal
Pada perangkat Android 1.x dan 2.x yang lebih lama, penyimpanan internal biasanya terletak di bagian khusus dari sistem file, dan bagian ini biasanya sangat kecil. HTC Dream (alias, T-Mobile G1), perangkat Android asli, memiliki memori internal 70 MB yang sangat besar untuk digunakan oleh semua aplikasi (ini bukan salah ketik, saat itu kami mengukur memori dalam megabyte).
Pada saat 2.3 perangkat keluar, penyimpanan internal bisa berukuran 1 GB.
Android 3.0 telah mengubah model penyimpanan, karena penyimpanan internal menjadi lebih bervolume. Untuk perangkat yang beriklan memiliki 4 GB, 8 GB, 16 GB, dll. ruang penyimpanan, biasanya semua ini (dikurangi konten yang ada) tersedia untuk penyimpanan internal. Kami akan melihat apa yang telah berubah di Android 3.0 dan dampaknya pada model penyimpanan di posting berikut tentang penyimpanan eksternal.
Untuk Android 1.x dan 2.x, penyimpanan internal hanya valid untuk file kecil, dan Anda harus menggunakan penyimpanan eksternal untuk yang lainnya. Android 3.0+ berarti bahwa untuk sebagian besar perangkat dan sebagian besar pengguna, penyimpanan internal sangat bagus untuk file yang tidak dimaksudkan untuk penggunaan normal oleh aplikasi lain atau yang dapat diakses oleh pengguna terlepas dari aplikasi Anda. Namun, beberapa pengguna berpengalaman menemukan bahwa bahkan flash on-board tidak cukup untuk apa yang ingin mereka simpan, sehingga mereka beralih ke penyimpanan yang dapat dilepas ... yang merupakan kaleng cacing (perhatikan λμινς) - sumber dari banyak masalah yang tidak dapat diprediksi dan kompleks.
FAQ Penyimpanan Internal
Haruskah saya membuat file di penyimpanan internal World-Readable atau World-Writeable?
Oh, $ ALLAH, tidak. Gunakan FileProvider
dan sajikan konten ini dengan penerapan ContentProvider
. Setelah itu, Anda, setidaknya, memiliki kesempatan untuk menggunakan sistem izin Android untuk mengontrol akses ke file-file ini, tidak seperti versi Anda, ketika aplikasi apa pun dalam sistem dapat merusak file-file ini.
Nah, bagaimana dengan android:sharedUserId
?
Saya tidak menyarankan.
android: sharedUserId
adalah atribut yang dapat Anda masukkan ke manifes yang menunjukkan pengidentifikasi logis pengguna yang akan digunakan untuk aplikasi Anda. Aplikasi lain apa pun yang diinstal yang menandatangani dengan kunci tanda tangan yang sama dan meminta android:sharedUserId
sama android:sharedUserId
akan menggunakan pengguna Linux yang sama dari sudut pandang keamanan. Efeknya adalah bahwa kedua aplikasi ini dapat bekerja dengan file satu sama lain dengan impunitas, karena file-file ini milik pengguna Linux yang sama.
Atribut ini benar-benar ditujukan untuk aplikasi pra-instal, seperti rangkaian perangkat lunak yang dimuat sebelumnya oleh pabrikan perangkat, operator seluler, atau pengembang firmware ROM yang dimodifikasi. Khususnya, segera setelah Anda menginstal aplikasi Anda sekali, Anda tidak dapat mengubah nilai android:sharedUserId
Anda tanpa rasa sakit android:sharedUserId
tanpa memblokir akses pengguna ke file yang ada ... karena Android tidak mengubah hak pemilik untuk file yang ada saat mengubah akun pengguna Linux, yang menjalankan aplikasi.
Ada berbagai risiko ketika beberapa proses mengakses file. Beberapa subsistem, seperti SQLite, memiliki logika bawaan untuk menyelesaikan masalah ini. Tetapi jika Anda sendiri mengatur akses Anda sendiri ke file (misalnya, melalui File
dan Java I / O), Anda perlu melakukan sesuatu dengan akses simultan, dan ini sulit.
Anda juga perlu menangani situasi di mana satu aplikasi menghapus instalan dengan menghapus file yang digunakan aplikasi lain. Dalam model hub-and-spoke, misalnya, dengan aplikasi dan satu set plugin, mungkin ini tidak terlalu berisiko. Dalam model lain, di mana aplikasi lebih adil, Anda tidak dapat kehilangan data aplikasi Anda hanya karena pengguna memutuskan untuk menghapus beberapa aplikasi terpisah.
Akhirnya, Anda tidak tahu apa yang bisa terjadi di masa depan. Saat ini, Anda dapat melihat suite aplikasi Anda sebagai suite yang sangat erat. Seseorang yang membeli aplikasi ini atau mengakuisisi perusahaan Anda mungkin ingin pergi ke arah lain. Menggunakan kemampuan berbagi data yang terhubung ContentProvider
, seperti ContentProvider
, memberi Anda lebih banyak fleksibilitas. Di dunia yang ideal, aplikasi Anda harus memperlakukan aplikasi lain sebagai sumber daya yang cukup andal, tetapi tidak selalu dapat diakses, seperti halnya layanan web Anda sendiri.
Bagaimana mencegah pengguna perangkat yang di-rooting mengakses file saya di penyimpanan internal?
Hanya saja, jangan menaruh file di penyimpanan internal. Pengguna perangkat yang di-rooting dapat mengakses apa yang mereka butuhkan di perangkat, jadi satu-satunya cara untuk mencegah mereka mengakses data Anda adalah dengan tidak memilikinya di perangkat.
Beberapa pengembang akan mencoba mengenkripsi file mereka dengan kata sandi yang dikodekan keras sehingga pengguna perangkat yang di-rooting tidak dapat menggunakan file-file ini. Ini akan membuat efek dari speed bump untuk waktu yang singkat. Yang diperlukan hanyalah satu orang yang tertarik untuk merekayasa balik aplikasi Anda, yang menentukan cara mendekripsi file-file ini, dan kemudian menulis pesan di blog atau forum tentang cara melakukan ini.
Secara umum, relatif sedikit orang dengan perangkat yang di-rooting - Saya menilainya kurang dari 1%. IMHO, Anda akan lebih berhasil dengan memfokuskan pekerjaan teknik Anda pada penulisan aplikasi yang lebih baik, daripada menghabiskan waktu melindungi dari perangkat yang di-rooting.