Computer >> Hướng Dẫn Máy Tính >  >> Hệ Thống >> Android

Hướng dẫn Android Storage: Sự tiến hóa, Loại và Best Practices

Storage (bộ nhớ) là thứ chúng ta đều biết, nhưng luôn coi như hiển nhiên. Không lâu trước, mỗi bước nhảy về dung lượng lưu trữ là tăng dần và dường như bất khả thi. Ngày nay, chúng ta không suy nghĩ lần hai khi cân nhắc thiết bị có bao nhiêu dung lượng (và không quan tâm đến sự khác biệt).

Điểm quan trọng hơn là xem sự tiến hóa của những gì được lưu trong bộ nhớ. Trước smartphone, chúng ta lưu vài bức ảnh, vài game và hàng tấn tin nhắn. Nhưng bây giờ, bất kỳ điện thoại tiêu chuẩn nào cũng có hỗn hợp ứng dụng, tài liệu, ảnh, video, file nhạc, và hơn thế nữa. Hãy tìm hiểu cách tận dụng không gian lưu trữ của thiết bị cho ứng dụng của chúng ta.

Chúng ta sẽ bao gồm trong bài viết này:

  1. Các loại storage khác nhau trên điện thoại Android
  2. Sự khác biệt giữa các loại storage
  3. Cách sử dụng storage trong ứng dụng

Mỗi ứng dụng có quyền truy cập vào hai loại storage khác nhau: internal (nội bộ) và external (ngoại bộ). Có sự khác biệt lớn giữa hai loại này, và biết chúng sẽ giúp bạn khi thiết kế ứng dụng tiếp theo.

Trước khi bắt đầu, một điều phải nói về storage và cache. Storage dành cho thứ bạn muốn lưu bền vững, trong khi cache lưu tạm thời.

Hướng dẫn Android Storage: Sự tiến hóa, Loại và Best Practices
Ảnh bởi Erda Estremera / Unsplash

Internal Storage (Bộ nhớ nội bộ)

Khi mỗi ứng dụng chạy trên hệ điều hành, nó có internal storage riêng. Storage này là private và chỉ dành cho ứng dụng đó. Nghĩa là, ứng dụng khác không thể truy cập, người dùng cũng không. Điều khác cần nhớ khi dùng internal storage là tính sẵn sàng của nó. Khác với external storage, internal storage luôn sẵn sàng cho ứng dụng.

Tuy nhiên, dùng storage này có nhược điểm. Nếu người dùng gỡ ứng dụng, tất cả dữ liệu lưu trong internal storage của app bị xóa theo. Hãy tưởng tượng bạn cài game, sau quyết định gỡ. Bạn muốn tiến độ game được lưu, nếu sau cài lại game.

Vậy làm sao để lưu file vào internal storage?

public void saveFileInternalStorage() { String FILENAME = "hello_world_file"; String inputToFile = "Hello From Internal Storage!"; try { FileOutputStream fileOutputStream = openFileOutput(FILENAME, Context.MODE_PRIVATE); fileOutputStream.write(inputToFile.getBytes()); fileOutputStream.close(); Toast.makeText(getApplicationContext(), "File " + FILENAME + " has been saved successfully", Toast.LENGTH_SHORT).show(); } catch (FileNotFoundException e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), "File " + FILENAME + " has not been saved successfully due to an exception " + e.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), "File " + FILENAME + " has not been saved successfully due to an exception " + e.getLocalizedMessage(), Toast.LENGTH_SHORT).show(); } }
Lưu file tên hello_world_file

Như bạn thấy, chúng ta lưu file hello_world_file chứa text “Hello From Internal Storage!”. Tôi tạo hai catch clause để demo exception có thể xảy ra, nhưng bạn có thể gộp thành một catch với Exception chung.

Chú ý method openFileOutput sẽ mở file nếu đã tồn tại, nếu không sẽ tạo mới. Tham số thứ hai là file mode. Tham số này chỉ định phạm vi file và quyền truy cập. Giá trị mặc định MODE_PRIVATE, chỉ app của bạn truy cập.

Hai giá trị khác MODE_WORLD_READABLE và MODE_WORLD_WRITEABLE, nhưng đã deprecated từ API 17. Chia sẻ file private với app khác dùng logic khác, đọc thêm tại đây. Cuối cùng, khi ghi file, chuyển string sang byte và đóng file.

Hướng dẫn Android Storage: Sự tiến hóa, Loại và Best Practices
Ảnh bởi Markus Spiske / Unsplash

External Storage (Bộ nhớ ngoại bộ)

Khác với cái tên ngụ ý, đây là storage được định nghĩa bởi việc nó không phải lúc nào cũng accessible. Có thể là thẻ SD card bên ngoài (secondary external storage), nhưng cũng có thể là storage trên thiết bị (primary external storage).

Để rõ ràng, external storage là storage có thể truy cập khi kết nối thiết bị với máy tính qua cáp USB. Như bạn đoán, bất cứ thứ gì lưu ở loại này đều accessible bởi app khác trên thiết bị, nhưng sẽ được giữ nếu bạn gỡ app.

Trước khi demo lưu file vào external storage, cần làm hai việc:

  1. Đảm bảo đủ dung lượng để lưu file
  2. Xin quyền tại runtime

Kiểm tra dung lượng cần code sau:

//Check if you can read/write to external storage public boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } return false; }
Kiểm tra có thể đọc/ghi external storage

Để truy cập external storage, thêm permission vào AndroidManifest.xml:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Quyền ghi external storage

Hơn nữa, từ API 23, dangerous permission không được cấp tại cài đặt mà tại runtime. Ghi external storage thuộc loại này, nên cần logic cho user quyết định cấp quyền hay không.

public void saveFileExternalStorage(View view) { if (isExternalStorageWritable()) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { writeFileToExternalStorage(); } else{ ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0); } } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case 0: { writeFileToExternalStorage(); break; } } }
Kiểm tra user đã cấp quyền

Method writeFileToExternalStorage như sau:

public void writeFileToExternalStorage() { String root = Environment.getExternalStorageDirectory().toString(); File myDir = new File(root + "/saved_files"); if (!myDir.exists()) { myDir.mkdirs(); } try { File file = new File(myDir, "myfile.txt"); FileOutputStream out = new FileOutputStream(file); out.write(inputToFile.getBytes()); out.close(); Toast.makeText(getApplicationContext(), "File myfile.txt" + " has been saved successfully to external storage", Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); } }
Ghi file vào external storage

Nếu muốn xem ví dụ đầy đủ code ở đây, truy cập repository GitHub này.

Hướng dẫn Android Storage: Sự tiến hóa, Loại và Best Practices
Ảnh bởi Steve Johnson / Unsplash

Tốt để biết

Trên chỉ là hai ví dụ đơn giản làm việc với các loại storage cho ứng dụng. Vì chúng ta deal với resource do hệ thống quản lý, nên cũng nên biết hành vi liên quan.

Mặc định, ứng dụng cài vào internal storage (xem giải thích internalOnly), nhưng từ API level 8, bạn có thể thêm attribute installLocation vào manifest cho phép app cài vào external storage. Lý do: nếu app rất lớn, bạn muốn user cài vào external storage vì nhiều không gian hơn.

Ba giá trị cho attribute:

  • auto - không có preference cụ thể nơi app cài. App sẽ thử cài internal, nếu đầy thì cài external
  • internalOnly - chỉ cài internal, nếu không đủ không gian thì không cài được
  • preferExternal - muốn cài external, nếu không đủ chỗ thì cài internal

Cả auto và preferExternal, user có option chuyển app từ external sang internal và ngược lại.

Lưu ý: khi user kết nối thiết bị với máy tính và cho phép chia sẻ data hoặc unmount SD card, tất cả app chạy từ external storage bị destroy. Nếu app dùng các tính năng sau, không nên cài vào external storage:

Các service khác nhau (đặc biệt alarm service), Input Method Engines, Live Wallpapers, App Widgets, Account Managers, Sync Adapters, Device Administrators và Broadcast receiver lắng nghe boot completed.