นี่คือการรวบรวมวิธีการทั่วไปในการบรรลุสิ่งนี้ :
- ส่งข้อมูลภายในเจตนา
- ฟิลด์คงที่
- HashMap ของ
WeakReferences
- วัตถุที่มีอยู่ (sqlite, การตั้งค่าการแชร์, ไฟล์, ฯลฯ )
TL; DR : มีสองวิธีในการแบ่งปันข้อมูล: การส่งข้อมูลในความพิเศษของเจตนาหรือบันทึกไว้ที่อื่น หากข้อมูลเป็นข้อมูลพื้นฐานสตริงหรือวัตถุที่ผู้ใช้กำหนด: ส่งเป็นส่วนหนึ่งของความตั้งใจพิเศษ (วัตถุที่ผู้ใช้กำหนดเองต้องนำมาใช้Parcelable
) หากผ่านวัตถุที่ซับซ้อนให้บันทึกอินสแตนซ์ในซิงเกิลตันที่อื่นและเข้าถึงจากกิจกรรมที่เรียกใช้
ตัวอย่างบางส่วนของวิธีการและเหตุผลที่จะใช้แต่ละวิธี:
ส่งข้อมูลภายในเจตนา
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("some_key", value);
intent.putExtra("some_other_key", "a value");
startActivity(intent);
ในกิจกรรมที่สอง:
Bundle bundle = getIntent().getExtras();
int value = bundle.getInt("some_key");
String value2 = bundle.getString("some_other_key");
ใช้วิธีนี้ถ้าคุณจะผ่านข้อมูลแบบดั้งเดิมหรือสตริง คุณยังสามารถส่งผ่านวัตถุที่ใช้งานSerializable
ได้
แม้ว่าจะดึงดูดคุณควรคิดให้รอบคอบก่อนใช้Serializable
: มันเกิดข้อผิดพลาดได้ง่ายและช้ามาก ดังนั้นโดยทั่วไป: อยู่ให้ห่างจากSerializable
ถ้าเป็นไปได้ หากคุณต้องการที่จะผ่านวัตถุที่ผู้ใช้กำหนดซับซ้อนใช้เวลาดูที่Parcelable
อินเตอร์เฟซ มันยากที่จะดำเนินการ Serializable
แต่ก็มีกำไรความเร็วมากเมื่อเทียบกับ
แบ่งปันข้อมูลโดยไม่ต้องต่อกับดิสก์
เป็นไปได้ที่จะแบ่งปันข้อมูลระหว่างกิจกรรมโดยบันทึกไว้ในหน่วยความจำเนื่องจากส่วนใหญ่กิจกรรมทั้งสองจะทำงานในกระบวนการเดียวกัน
หมายเหตุ:บางครั้งเมื่อผู้ใช้ออกจากกิจกรรมของคุณ (โดยไม่เลิก) Android อาจตัดสินใจฆ่าแอปพลิเคชันของคุณ ในสถานการณ์เช่นนี้ฉันมีกรณีที่ Android พยายามเปิดกิจกรรมล่าสุดโดยใช้เจตนาที่มีให้ก่อนที่แอปจะถูกฆ่า ในกรณีนี้ข้อมูลที่เก็บไว้ในซิงเกิลตัน (ของคุณหรือApplication
) จะหายไปและสิ่งเลวร้ายอาจเกิดขึ้นได้ เพื่อหลีกเลี่ยงกรณีดังกล่าวคุณคงอยู่วัตถุไปยังดิสก์หรือตรวจสอบข้อมูลก่อนที่จะใช้เพื่อให้แน่ใจว่าถูกต้อง
ใช้คลาสเดี่ยว
มีคลาสสำหรับเก็บข้อมูล:
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;}
}
จากกิจกรรมที่เปิดตัว:
String data = DataHolder.getInstance().getData();
ใช้แอปพลิเคชันเดี่ยว
แอปพลิเคชันซิงเกิลตันเป็นอินสแตนซ์android.app.Application
ที่สร้างขึ้นเมื่อเปิดตัวแอพ คุณสามารถกำหนดเองได้โดยขยาย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;}
}
ก่อนเริ่มกิจกรรม:
MyApplication app = (MyApplication) getApplicationContext();
app.setData(someData);
จากนั้นจากกิจกรรมที่เปิดตัว:
MyApplication app = (MyApplication) getApplicationContext();
String data = app.getData();
ฟิลด์คงที่
ความคิดนั้นเหมือนกับซิงเกิล แต่ในกรณีนี้คุณให้การเข้าถึงข้อมูลแบบคงที่:
public class DataHolder {
private static String data;
public static String getData() {return data;}
public static void setData(String data) {DataHolder.data = data;}
}
จากกิจกรรมที่เปิดตัว:
String data = DataHolder.getData();
HashMap ของ WeakReferences
แนวคิดเดียวกัน แต่อนุญาตให้ตัวรวบรวมขยะลบวัตถุที่ไม่อ้างอิง (เช่นเมื่อผู้ใช้ออกจากกิจกรรม):
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();
}
}
ก่อนเริ่มกิจกรรม:
DataHolder.getInstance().save(someId, someObject);
จากกิจกรรมที่เปิดตัว:
DataHolder.getInstance().retrieve(someId);
คุณอาจจะหรืออาจไม่จำเป็นต้องผ่าน ID วัตถุโดยใช้ความพิเศษของเจตนา ทุกอย่างขึ้นอยู่กับปัญหาเฉพาะของคุณ
คงวัตถุไว้ในดิสก์
แนวคิดคือการบันทึกข้อมูลลงในดิสก์ก่อนที่จะเปิดกิจกรรมอื่น ๆ
ข้อดี:คุณสามารถเริ่มกิจกรรมจากที่อื่นได้และหากข้อมูลยังคงอยู่มันควรจะทำงานได้ดี
ข้อเสีย:มันยุ่งยากและใช้เวลาในการดำเนินการมากขึ้น ต้องใช้รหัสมากขึ้นและมีโอกาสมากขึ้นในการแนะนำข้อบกพร่อง มันจะช้ากว่ามาก
วิธีในการคงอยู่ของวัตถุมีดังนี้: