Lưu trữ là điều mà tất cả chúng ta đều nhận thức được, nhưng luôn coi đó là điều hiển nhiên. Cách đây không lâu, mọi bước nhảy vọt về dung lượng lưu trữ đều tăng lên và dường như là không thể. Ngày nay, chúng tôi không suy nghĩ kỹ khi xem xét các thiết bị của chúng tôi có bao nhiêu phần trăm (và không thể quan tâm hơn đến sự khác biệt).
Một điểm quan trọng hơn là xem xét sự phát triển của những gì được lưu trữ trong bộ nhớ. Trước khi có điện thoại thông minh, chúng tôi thỉnh thoảng lưu một hoặc hai bức ảnh, một số trò chơi và rất nhiều tin nhắn văn bản. Nhưng bây giờ, bất kỳ điện thoại tiêu chuẩn nào cũng sẽ có một tập hợp các ứng dụng, tài liệu, ảnh, video, tệp nhạc và hơn thế nữa. Hãy cùng tìm hiểu cách chúng tôi có thể sử dụng không gian lưu trữ của thiết bị cho các ứng dụng của mình.
Những gì chúng ta sẽ đề cập trong bài viết này là:
- Các loại bộ nhớ khác nhau trên điện thoại Android
- Sự khác biệt giữa các loại bộ nhớ
- Cách sử dụng bộ nhớ trong ứng dụng của bạn
Mỗi ứng dụng có quyền truy cập vào hai loại bộ nhớ khác nhau: nội bộ và bên ngoài . Có sự khác biệt chính giữa hai loại lưu trữ này và biết chúng sẽ giúp bạn khi thiết kế ứng dụng tiếp theo của mình.
Trước khi chúng ta bắt đầu, cần phải nói một điều về bộ nhớ và bộ nhớ cache. Bộ nhớ dành cho những thứ bạn muốn lưu liên tục, trong khi bộ nhớ cache ở đó để lưu mọi thứ tạm thời.
Bộ nhớ trong
Khi mỗi ứng dụng được chạy trên hệ điều hành, nó có bộ nhớ trong riêng. Bộ nhớ này là riêng tư và chỉ để sử dụng ứng dụng. Có nghĩa là, các ứng dụng khác không thể truy cập nó, và người dùng cũng không thể. Một điều khác cần lưu ý khi sử dụng bộ nhớ trong là tính khả dụng của nó. Không giống như bộ nhớ ngoài, bộ nhớ trong luôn có sẵn cho ứng dụng của bạn.
Tuy nhiên, việc sử dụng bộ nhớ này có những hạn chế của nó. Nếu người dùng xóa ứng dụng, tất cả dữ liệu được lưu trữ trong bộ nhớ trong của ứng dụng của bạn cũng sẽ bị xóa. Hãy tưởng tượng điều gì sẽ xảy ra nếu bạn cài đặt một trò chơi trên điện thoại của mình và một nơi nào đó trên đường đã quyết định xóa nó. Bạn muốn lưu tiến trình trò chơi của mình, nếu có cơ hội bạn sẽ cài đặt lại trò chơi.
Vậy, làm cách nào để lưu tệp vào bộ nhớ trong?
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();
}
}
Như bạn có thể thấy trong ví dụ mã, chúng tôi đang lưu một tệp có tên hello_world_file chứa văn bản “Xin chào từ bộ nhớ trong!” . Tôi đã tạo hai mệnh đề bắt chỉ để chứng minh các ngoại lệ có thể xảy ra khi cố gắng thực hiện việc này, nhưng bạn có thể giảm thiểu chúng thành một mệnh đề bắt với đối tượng Ngoại lệ chung.
Hãy chú ý rằng phương pháp openFileOutput sẽ mở tệp nếu nó đã tồn tại, nhưng nếu chưa, sẽ tạo nó. Tham số thứ hai của phương thức này là chế độ tệp. Tham số này chỉ định phạm vi của tệp và quyền truy cập vào nó. Giá trị mặc định là MODE_PRIVATE, làm cho tệp chỉ có thể truy cập vào ứng dụng của bạn.
Hai giá trị khác cho tham số này là MODE_WORLD_READABLE và MODE_WORLD_WRITEABLE, nhưng chúng đã không được chấp nhận kể từ API 17. Chia sẻ tệp riêng tư với các ứng dụng khác sử dụng một tập hợp logic khác mà bạn có thể đọc thêm tại đây. Cuối cùng, khi ghi vào tệp, chúng tôi chuyển đổi chuỗi của mình thành byte và chúng tôi đảm bảo đóng tệp ở cuối.
Bộ nhớ ngoài
Trái ngược với những gì tên ngụ ý, đây là bộ nhớ được định nghĩa bởi thực tế là nó không phải lúc nào cũng có thể truy cập được. Điều này có thể có nghĩa là nó có thể là thẻ SD bên ngoài (bộ nhớ ngoài thứ cấp), nhưng nó cũng có thể là bộ nhớ được tìm thấy trên thiết bị (bộ nhớ ngoài chính).
Để mang sự thật về nhà, bộ nhớ ngoài là bộ nhớ có thể được truy cập khi bạn kết nối thiết bị của mình với máy tính qua cáp USB. Như bạn có thể đã đoán, mọi thứ được lưu trữ trong loại bộ nhớ này đều có thể truy cập được đối với các ứng dụng khác trên thiết bị của bạn, nhưng sẽ được giữ lại nếu bạn gỡ cài đặt ứng dụng.
Trước khi có thể trình bày cách lưu tệp vào bộ nhớ ngoài, chúng ta cần thực hiện hai việc:
- Đảm bảo có đủ dung lượng để lưu tệp
- Yêu cầu quyền trong thời gian chạy
Đảm bảo có đủ dung lượng lưu trữ yêu cầu các dòng mã 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;
}
Để có quyền truy cập vào bộ nhớ ngoài, chúng tôi cần thêm quyền sau vào AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Hơn nữa, kể từ API 23, các quyền nguy hiểm không được cấp phép trong thời gian cài đặt mà là trong thời gian chạy. Việc ghi vào bộ nhớ ngoài được phân loại là một, vì vậy chúng tôi cần thêm logic để cho phép người dùng quyết định có cấp quyền cho ứng dụng 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;
}
}
}
writeFileToExternalStorage của chúng tôi trông như thế này:
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();
}
}
Nếu bạn muốn xem ví dụ về tất cả mã được trình bày ở đây, bạn có thể truy cập kho lưu trữ GitHub này.
Điều cần biết
Trên đây chỉ là hai ví dụ đơn giản về cách làm việc với các loại bộ nhớ khác nhau cho ứng dụng của bạn. Vì chúng ta đang xử lý tài nguyên mà hệ thống quản lý, chúng ta cũng nên biết về các hành vi liên quan đến nó.
Theo mặc định, ứng dụng của bạn sẽ được cài đặt vào bộ nhớ trong ( xem giải thích InternalOnly ), nhưng từ API cấp 8, bạn có thể thêm một thuộc tính, installLocation , vào tệp kê khai của bạn để cho phép ứng dụng của bạn được cài đặt vào bộ nhớ ngoài. Một lý do để làm như vậy là nếu ứng dụng của bạn rất lớn và bạn muốn người dùng cài đặt ứng dụng đó trên bộ nhớ ngoài của thiết bị vì ở đó có nhiều dung lượng hơn.
Có ba giá trị cho thuộc tính này:
- tự động - có nghĩa là bạn không có tùy chọn cụ thể nơi ứng dụng sẽ được cài đặt. Ứng dụng sẽ cố gắng được cài đặt vào bộ nhớ trong, nhưng nếu đầy, ứng dụng sẽ cài đặt bên trong bộ nhớ ngoài
- InternalOnly - ứng dụng sẽ chỉ được cài đặt vào bộ nhớ trong và nếu không có đủ dung lượng ở đó, ứng dụng sẽ không được cài đặt
- ưa thích Bên ngoài - có nghĩa là bạn muốn ứng dụng của mình được cài đặt vào bộ nhớ ngoài, nhưng nếu không có đủ dung lượng ở đó, ứng dụng sẽ được cài đặt nội bộ
Đối với cả tùy chọn tự động và tùy chọn bên ngoài, người dùng có tùy chọn di chuyển ứng dụng từ bộ nhớ ngoài vào bộ nhớ trong và ngược lại.
Hãy nhớ rằng sau khi người dùng kết nối thiết bị của họ với máy tính và cho phép thiết bị đó chia sẻ dữ liệu hoặc ngắt kết nối thẻ SD, tất cả các ứng dụng đang chạy từ bộ nhớ ngoài sẽ bị phá hủy. Nếu ứng dụng của bạn sử dụng một trong các tính năng sau, bạn không nên cài đặt nó vào bộ nhớ ngoài:
Các dịch vụ khác nhau (dịch vụ báo động s ặc biệt), Công cụ phương thức nhập, Hình nền động, Tiện ích ứng dụng, Người quản lý tài khoản, Bộ điều hợp đồng bộ hóa, Quản trị viên thiết bị và Bộ thu phát sóng đang lắng nghe khởi động hoàn tất.