Dưới đây là tổng hợp các cách phổ biến nhất để đạt được điều này :
- Gửi dữ liệu trong ý định
- Các trường tĩnh
- HashMap của
WeakReferences
- Các đối tượng bền bỉ (sqlite, chia sẻ tùy chọn, tệp, v.v.)
TL; DR : có hai cách chia sẻ dữ liệu: truyền dữ liệu trong phần bổ sung của mục đích hoặc lưu nó ở nơi khác. Nếu dữ liệu là nguyên thủy, Chuỗi hoặc đối tượng do người dùng xác định: gửi dữ liệu đó như một phần của phần bổ sung ý định (đối tượng do người dùng xác định phải triển khai Parcelable
). Nếu vượt qua các đối tượng phức tạp, hãy lưu một thể hiện trong một singleton ở một nơi khác và truy cập chúng từ hoạt động đã khởi chạy.
Một số ví dụ về cách thức và lý do thực hiện từng phương pháp:
Gửi dữ liệu bên trong ý định
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("some_key", value);
intent.putExtra("some_other_key", "a value");
startActivity(intent);
Về hoạt động thứ hai:
Bundle bundle = getIntent().getExtras();
int value = bundle.getInt("some_key");
String value2 = bundle.getString("some_other_key");
Sử dụng phương pháp này nếu bạn đang truyền dữ liệu nguyên thủy hoặc Chuỗi . Bạn cũng có thể vượt qua các đối tượng thực hiện Serializable
.
Mặc dù hấp dẫn, bạn nên suy nghĩ kỹ trước khi sử dụng Serializable
: nó dễ bị lỗi và chậm kinh khủng. Vì vậy, nói chung: tránh xaSerializable
nếu có thể. Nếu bạn muốn vượt qua các đối tượng phức tạp do người dùng xác định, hãy xem Parcelable
giao diện . Khó thực hiện hơn, nhưng nó có tốc độ tăng đáng kể so với Serializable
.
Chia sẻ dữ liệu mà không cần lưu vào đĩa
Có thể chia sẻ dữ liệu giữa các hoạt động bằng cách lưu nó vào bộ nhớ do trong hầu hết các trường hợp, cả hai hoạt động đều chạy trong cùng một quy trình.
Lưu ý: đôi khi, khi người dùng rời khỏi hoạt động của bạn (mà không thoát khỏi nó), Android có thể quyết định hủy ứng dụng của bạn. Trong kịch bản như vậy, tôi đã gặp phải trường hợp Android cố gắng khởi chạy hoạt động cuối cùng bằng cách sử dụng ý định được cung cấp trước khi ứng dụng bị giết. Trong trường hợp này, dữ liệu được lưu trữ trong một singleton (của bạn hoặc Application
) sẽ biến mất và điều tồi tệ có thể xảy ra. Để tránh những trường hợp như vậy, bạn hoặc duy trì các đối tượng vào đĩa hoặc kiểm tra dữ liệu trước khi sử dụng để đảm bảo nó hợp lệ.
Sử dụng một lớp đơn
Có một lớp để giữ dữ liệu:
public class DataHolder {
private String data;
public String getData() {return data;}
public void setData(String data) {this.data = data;}
private static final DataHolder holder = new DataHolder();
public static DataHolder getInstance() {return holder;}
}
Từ hoạt động ra mắt:
String data = DataHolder.getInstance().getData();
Sử dụng ứng dụng đơn
Ứng dụng singleton là một phiên bản android.app.Application
được tạo khi ứng dụng được khởi chạy. Bạn có thể cung cấp một tùy chỉnh bằng cách mở rộng Application
:
import android.app.Application;
public class MyApplication extends Application {
private String data;
public String getData() {return data;}
public void setData(String data) {this.data = data;}
}
Trước khi ra mắt hoạt động:
MyApplication app = (MyApplication) getApplicationContext();
app.setData(someData);
Sau đó, từ hoạt động ra mắt:
MyApplication app = (MyApplication) getApplicationContext();
String data = app.getData();
Các trường tĩnh
Ý tưởng về cơ bản giống như singleton, nhưng trong trường hợp này bạn cung cấp quyền truy cập tĩnh vào dữ liệu:
public class DataHolder {
private static String data;
public static String getData() {return data;}
public static void setData(String data) {DataHolder.data = data;}
}
Từ hoạt động ra mắt:
String data = DataHolder.getData();
HashMap của WeakReferences
Cùng một ý tưởng, nhưng cho phép trình thu gom rác loại bỏ các đối tượng không được ước tính (ví dụ: khi người dùng thoát khỏi hoạt động):
public class DataHolder {
Map<String, WeakReference<Object>> data = new HashMap<String, WeakReference<Object>>();
void save(String id, Object object) {
data.put(id, new WeakReference<Object>(object));
}
Object retrieve(String id) {
WeakReference<Object> objectWeakReference = data.get(id);
return objectWeakReference.get();
}
}
Trước khi ra mắt hoạt động:
DataHolder.getInstance().save(someId, someObject);
Từ hoạt động ra mắt:
DataHolder.getInstance().retrieve(someId);
Bạn có thể hoặc không phải vượt qua id đối tượng bằng cách sử dụng các tính năng bổ sung của ý định. Tất cả phụ thuộc vào vấn đề cụ thể của bạn.
Kiên trì các đối tượng vào đĩa
Ý tưởng là lưu dữ liệu trong đĩa trước khi khởi chạy hoạt động khác.
Ưu điểm: bạn có thể khởi chạy hoạt động từ những nơi khác và, nếu dữ liệu đã được duy trì, nó sẽ hoạt động tốt.
Nhược điểm: nó cồng kềnh và mất nhiều thời gian hơn để thực hiện. Yêu cầu nhiều mã hơn và do đó có nhiều cơ hội giới thiệu lỗi hơn. Nó cũng sẽ chậm hơn nhiều.
Một số cách để duy trì các đối tượng bao gồm: