ฉันจะส่งผ่านวัตถุประเภทที่กำหนดเองจากกิจกรรมหนึ่งไปยังอีกกิจกรรมหนึ่งโดยใช้
putExtra()
วิธีการของคลาสIntent ได้อย่างไร
ฉันจะส่งผ่านวัตถุประเภทที่กำหนดเองจากกิจกรรมหนึ่งไปยังอีกกิจกรรมหนึ่งโดยใช้
putExtra()
วิธีการของคลาสIntent ได้อย่างไร
คำตอบ:
หากคุณเพิ่งผ่านวัตถุไปรอบ ๆParcelableได้รับการออกแบบมาสำหรับสิ่งนี้ มันต้องใช้ความพยายามเล็ก ๆ น้อย ๆ มากขึ้นในการใช้งานมากกว่าการใช้เป็นอันดับพื้นเมืองของ Java แต่มันเป็นวิธีที่เร็วขึ้น (และฉันวิธีเฉลี่ยWAYเร็วกว่า)
จากเอกสารตัวอย่างง่ายๆสำหรับการใช้งานคือ:
// simple class that just has one member property as an example
public class MyParcelable implements Parcelable {
private int mData;
/* everything below here is for implementing Parcelable */
// 99.9% of the time you can just ignore this
@Override
public int describeContents() {
return 0;
}
// write your object's data to the passed-in Parcel
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
// this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
// example constructor that takes a Parcel and gives you an object populated with it's values
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
สังเกตว่าในกรณีที่คุณมีมากกว่าหนึ่งช่องที่จะเรียกคืนจากพัสดุที่กำหนดคุณต้องทำตามลำดับเดียวกับที่คุณใส่ไว้ (นั่นคือในแนวทางแบบ FIFO)
เมื่อคุณมีวัตถุของคุณใช้Parcelable
มันเป็นเพียงแค่เรื่องของการวางพวกเขาเป็นของคุณเจตจำนงกับputExtra () :
Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);
จากนั้นคุณสามารถดึงออกมาด้วยgetParcelableExtra () :
Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");
หาก Object Class ของคุณใช้ Parcelable และ Serializable จากนั้นตรวจสอบให้แน่ใจว่าคุณได้เลือกหนึ่งในสิ่งต่อไปนี้
i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);
คุณจะต้องทำให้เป็นอันดับวัตถุของคุณเป็นตัวแทนสตริงบางชนิด หนึ่งในการแสดงสตริงเป็นไปได้คือ JSON และหนึ่งในวิธีที่ง่ายที่สุดที่จะเป็นอันดับจาก / ไป JSON ในหุ่นยนต์ถ้าคุณถามผมคือผ่านGoogle GSON
ในกรณีนี้คุณเพียงแค่ใส่ค่าส่งคืนสตริงจาก(new Gson()).toJson(myObject);
และดึงค่าสตริงและใช้fromJson
เพื่อเปลี่ยนกลับเป็นวัตถุของคุณ
อย่างไรก็ตามหากวัตถุของคุณไม่ซับซ้อนมากมันอาจไม่คุ้มกับค่าใช้จ่ายและคุณสามารถพิจารณาส่งผ่านค่าแยกของวัตถุแทน
String s = (new Gson().toJson(client));
แล้วCli client = new Gson().fromJson(s, Cli.class);
คุณสามารถส่งวัตถุที่สามารถทำให้เป็นอนุกรมได้ผ่านจุดประสงค์
// send where details is object
ClassName details = new ClassName();
Intent i = new Intent(context, EditActivity.class);
i.putExtra("Editing", details);
startActivity(i);
//receive
ClassName model = (ClassName) getIntent().getSerializableExtra("Editing");
And
Class ClassName implements Serializable {
}
Serializable
แต่ไม่ก็ไม่ค่อยคุ้มค่าการรบกวนที่จะทำให้มันParcelable
Parcelable
สำหรับสถานการณ์ที่คุณรู้ว่าคุณกำลังส่งผ่านข้อมูลภายในแอปพลิเคชันให้ใช้ "globals" (เช่นคลาสคงที่)
นี่คือสิ่งที่Dianne Hackborn (hackbod - วิศวกรซอฟต์แวร์ Google Android) ได้กล่าวไว้ในเรื่องนี้:
สำหรับสถานการณ์ที่คุณรู้ว่ากิจกรรมกำลังทำงานในกระบวนการเดียวกันคุณสามารถแบ่งปันข้อมูลผ่านทาง globals ตัวอย่างเช่นคุณสามารถมีทั่วโลก
HashMap<String, WeakReference<MyInterpreterState>>
และเมื่อคุณสร้าง MyInterpreterState ใหม่ขึ้นมาด้วยชื่อที่ไม่ซ้ำกันและวางไว้ในแผนที่แฮช เพื่อส่งสถานะนั้นไปยังกิจกรรมอื่นเพียงแค่ใส่ชื่อที่ไม่ซ้ำกันลงในแผนที่แฮชและเมื่อกิจกรรมที่สองเริ่มขึ้นสามารถเรียก MyInterpreterState จากแผนที่แฮชที่มีชื่อที่ได้รับ
คลาสของคุณควรใช้ Serializable หรือ Parcelable
public class MY_CLASS implements Serializable
เมื่อเสร็จแล้วคุณสามารถส่งวัตถุบน putExtra
intent.putExtra("KEY", MY_CLASS_instance);
startActivity(intent);
เพื่อรับความพิเศษคุณต้องทำ
Intent intent = getIntent();
MY_CLASS class = (MY_CLASS) intent.getExtras().getSerializable("KEY");
หากชั้นเรียนของคุณใช้งาน Parcelable ได้ในครั้งต่อไป
MY_CLASS class = (MY_CLASS) intent.getExtras().getParcelable("KEY");
ฉันหวังว่ามันจะช่วย: D
Serializable
ผิด ชั้นสามารถใช้Parcelable
ตัวอย่างเช่น
Serializable
เป็นอินเทอร์เฟซ Java มาตรฐานParcelable
เป็นเฉพาะ Android ในแง่ของประสิทธิภาพ Parcelable มีประสิทธิภาพมากขึ้น: developerphil.com/parcelable-vs-serializable
คำตอบสั้น ๆ สำหรับความต้องการที่รวดเร็ว
1. ใช้คลาสของคุณเป็นอนุกรม
หากคุณมีคลาสภายในใด ๆ อย่าลืมนำไปใช้กับ Serializable ด้วย !!
public class SportsData implements Serializable
public class Sport implements Serializable
List<Sport> clickedObj;
2. ใส่วัตถุของคุณเป็นเจตนา
Intent intent = new Intent(SportsAct.this, SportSubAct.class);
intent.putExtra("sport", clickedObj);
startActivity(intent);
3. และรับวัตถุของคุณใน Activity Class อื่น
Intent intent = getIntent();
Sport cust = (Sport) intent.getSerializableExtra("sport");
หากคลาสอ็อบเจ็กต์ของคุณใช้งานSerializable
คุณไม่จำเป็นต้องทำอะไรอีกคุณสามารถส่งวัตถุที่ต่อเนื่องกันได้
นั่นคือสิ่งที่ฉันใช้
ใช้เป็นอนุกรมในชั้นเรียนของคุณ
public class Place implements Serializable{
private int id;
private String name;
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
จากนั้นคุณสามารถผ่านวัตถุนี้โดยเจตนา
Intent intent = new Intent(this, SecondAct.class);
intent.putExtra("PLACE", Place);
startActivity(intent);
int กิจกรรมที่สองคุณจะได้รับข้อมูลเช่นนี้
Place place= (Place) getIntent().getSerializableExtra("PLACE");
แต่เมื่อข้อมูลมีขนาดใหญ่วิธีนี้จะช้า
มีสองวิธีที่คุณสามารถเข้าถึงตัวแปรหรือวัตถุในคลาสหรือกิจกรรมอื่น ๆ
A. ฐานข้อมูล
B. ค่ากำหนดที่แชร์
C. การทำให้เป็นอันดับวัตถุ
D. คลาสที่สามารถเก็บข้อมูลทั่วไปสามารถตั้งชื่อเป็น Common Utilities ขึ้นอยู่กับคุณ
E. การส่งข้อมูลผ่าน Intents และ Parcelable Interface
ขึ้นอยู่กับความต้องการของโครงการของคุณ
A. ฐานข้อมูล
SQLite เป็นฐานข้อมูลโอเพ่นซอร์สซึ่งถูกฝังลงใน Android SQLite รองรับคุณสมบัติฐานข้อมูลเชิงสัมพันธ์มาตรฐานเช่นไวยากรณ์ SQL ธุรกรรมและข้อความสั่งที่เตรียมไว้
บทช่วยสอน - http://www.vogella.com/articles/AndroidSQLite/article.html
B. การตั้งค่าที่ใช้ร่วมกัน
สมมติว่าคุณต้องการเก็บชื่อผู้ใช้ ดังนั้นตอนนี้จะมีสองสิ่งคือชื่อผู้ใช้ที่สำคัญค่าที่คุ้มค่า
วิธีการจัดเก็บ
// Create object of SharedPreferences.
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
//now get Editor
SharedPreferences.Editor editor = sharedPref.edit();
//put your value
editor.putString("userName", "stackoverlow");
//commits your edits
editor.commit();
ใช้ putString (), putBoolean (), putInt (), putFloat (), putLong () คุณสามารถบันทึก dtatype ที่คุณต้องการ
วิธีดึงข้อมูล
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");
http://developer.android.com/reference/android/content/SharedPreferences.html
C. การทำให้เป็นอันดับวัตถุ
การรวมวัตถุนั้นใช้ถ้าเราต้องการบันทึกสถานะวัตถุเพื่อส่งผ่านเครือข่ายหรือคุณสามารถใช้เพื่อวัตถุประสงค์ของคุณได้เช่นกัน
ใช้ java beans และเก็บไว้ในนั้นเป็นหนึ่งในฟิลด์ของเขาและใช้ getters และ setter สำหรับสิ่งนั้น
JavaBeans เป็นคลาส Java ที่มีคุณสมบัติ คิดว่าคุณสมบัติเป็นตัวแปรอินสแตนซ์ส่วนตัว เนื่องจากพวกเขาเป็นส่วนตัววิธีเดียวที่พวกเขาสามารถเข้าถึงได้จากนอกห้องเรียนของพวกเขาคือผ่านวิธีการในชั้นเรียน เมธอดที่เปลี่ยนค่าของคุณสมบัติเรียกว่าเมธอด setter และเมธอดที่ดึงค่าของคุณสมบัติเรียกว่าเมธอด getter
public class VariableStorage implements Serializable {
private String inString ;
public String getInString() {
return inString;
}
public void setInString(String inString) {
this.inString = inString;
}
}
ตั้งค่าตัวแปรในเมล์ของคุณโดยใช้
VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);
จากนั้นใช้วัตถุ Serialzation เพื่อทำให้เป็นอันดับวัตถุนี้และในชั้นอื่น ๆ ของคุณ deserialize วัตถุนี้
ในการทำให้เป็นอันดับวัตถุสามารถแสดงเป็นลำดับของไบต์ที่มีข้อมูลของวัตถุรวมทั้งข้อมูลเกี่ยวกับประเภทของวัตถุและประเภทของข้อมูลที่เก็บไว้ในวัตถุ
หลังจากที่วัตถุที่เป็นอนุกรมได้รับการเขียนลงในไฟล์มันสามารถอ่านได้จากไฟล์และ deserialized นั่นคือข้อมูลประเภทและไบต์ที่เป็นตัวแทนของวัตถุและข้อมูลที่สามารถใช้ในการสร้างวัตถุในหน่วยความจำ
หากคุณต้องการกวดวิชาสำหรับการอ้างอิงลิงค์นี้
http://javawithswaranga.blogspot.in/2011/08/serialization-in-java.html
D. CommonUtilities
คุณสามารถสร้างคลาสได้ด้วยตนเองซึ่งสามารถมีข้อมูลทั่วไปที่คุณต้องการบ่อยในโครงการของคุณ
ตัวอย่าง
public class CommonUtilities {
public static String className = "CommonUtilities";
}
E. การส่งข้อมูลผ่านเจตนา
โปรดอ้างอิงบทช่วยสอนนี้สำหรับตัวเลือกการส่งผ่านข้อมูลนี้
คุณสามารถใช้ Android BUNDLE เพื่อทำสิ่งนี้
สร้าง Bundle จากชั้นเรียนของคุณเช่น:
public Bundle toBundle() {
Bundle b = new Bundle();
b.putString("SomeKey", "SomeValue");
return b;
}
จากนั้นส่งชุดนี้ด้วยเจตนา ตอนนี้คุณสามารถสร้างคลาสวัตถุของคุณใหม่โดยส่งบันเดิลแบบนี้
public CustomClass(Context _context, Bundle b) {
context = _context;
classMember = b.getString("SomeKey");
}
ประกาศสิ่งนี้ในคลาสที่คุณกำหนดเองและใช้งาน
ขอบคุณสำหรับความช่วยเหลือที่พัสดุ แต่ฉันพบวิธีแก้ปัญหาเพิ่มเติมอีกทางเลือกหนึ่ง
public class getsetclass implements Serializable {
private int dt = 10;
//pass any object, drwabale
public int getDt() {
return dt;
}
public void setDt(int dt) {
this.dt = dt;
}
}
ในกิจกรรมที่หนึ่ง
getsetclass d = new getsetclass ();
d.setDt(50);
LinkedHashMap<String, Object> obj = new LinkedHashMap<String, Object>();
obj.put("hashmapkey", d);
Intent inew = new Intent(SgParceLableSampelActivity.this,
ActivityNext.class);
Bundle b = new Bundle();
b.putSerializable("bundleobj", obj);
inew.putExtras(b);
startActivity(inew);
รับข้อมูลในกิจกรรม 2
try { setContentView(R.layout.main);
Bundle bn = new Bundle();
bn = getIntent().getExtras();
HashMap<String, Object> getobj = new HashMap<String, Object>();
getobj = (HashMap<String, Object>) bn.getSerializable("bundleobj");
getsetclass d = (getsetclass) getobj.get("hashmapkey");
} catch (Exception e) {
Log.e("Err", e.getMessage());
}
ฉันใช้ Gson กับ API ที่ทรงพลังและเรียบง่ายเพื่อส่งวัตถุระหว่างกิจกรรม
ตัวอย่าง
// This is the object to be sent, can be any object
public class AndroidPacket {
public String CustomerName;
//constructor
public AndroidPacket(String cName){
CustomerName = cName;
}
// other fields ....
// You can add those functions as LiveTemplate !
public String toJson() {
Gson gson = new Gson();
return gson.toJson(this);
}
public static AndroidPacket fromJson(String json) {
Gson gson = new Gson();
return gson.fromJson(json, AndroidPacket.class);
}
}
2 ฟังก์ชั่นที่คุณเพิ่มเข้าไปในวัตถุที่คุณต้องการส่ง
การใช้
ส่งวัตถุจาก A ถึง B
// Convert the object to string using Gson
AndroidPacket androidPacket = new AndroidPacket("Ahmad");
String objAsJson = androidPacket.toJson();
Intent intent = new Intent(A.this, B.class);
intent.putExtra("my_obj", objAsJson);
startActivity(intent);
รับเป็น B
@Override
protected void onCreate(Bundle savedInstanceState) {
Bundle bundle = getIntent().getExtras();
String objAsJson = bundle.getString("my_obj");
AndroidPacket androidPacket = AndroidPacket.fromJson(objAsJson);
// Here you can use your Object
Log.d("Gson", androidPacket.CustomerName);
}
ฉันใช้มันเกือบทุกโครงการที่ฉันทำและไม่มีปัญหาเรื่องประสิทธิภาพ
ฉันต่อสู้กับปัญหาเดียวกัน ฉันแก้ไขมันโดยใช้คลาสแบบคงที่จัดเก็บข้อมูลใด ๆ ที่ฉันต้องการใน HashMap ด้านบนฉันใช้ส่วนขยายของคลาสกิจกรรมมาตรฐานที่ฉันได้ overriden วิธีการในการสร้าง onDestroy เพื่อทำการขนส่งข้อมูลและการล้างข้อมูลที่ซ่อนอยู่ ต้องเปลี่ยนการตั้งค่าที่ไร้สาระบางอย่างเช่นการจัดการแนว
คำอธิบายประกอบ: การไม่ให้สิ่งของทั่วไปที่จะส่งผ่านไปยังกิจกรรมอื่นคือความเจ็บปวดในตูด มันเหมือนกับการถ่ายภาพตัวเองที่หัวเข่าและหวังว่าจะชนะได้ 100 เมตร "Parcable" ไม่ใช่สิ่งทดแทนที่เพียงพอ มันทำให้ฉันหัวเราะ ... ฉันไม่ต้องการที่จะใช้อินเทอร์เฟซนี้กับ API ที่ปราศจากเทคโนโลยีของฉันเพราะฉันต้องการที่จะแนะนำเลเยอร์ใหม่ ... เป็นไปได้อย่างไรที่เราอยู่ในการเขียนโปรแกรมมือถือ กระบวนทัศน์ที่ทันสมัย ...
ในกิจกรรมแรกของคุณ:
intent.putExtra("myTag", yourObject);
และในวินาทีที่สองของคุณ:
myCustomObject myObject = (myCustomObject) getIntent().getSerializableExtra("myTag");
อย่าลืมที่จะทำให้วัตถุของคุณเป็นอนุกรม:
public class myCustomObject implements Serializable {
...
}
อีกวิธีในการทำเช่นนี้คือการใช้Application
วัตถุ (android.app.Application) คุณกำหนดสิ่งนี้ในAndroidManifest.xml
ไฟล์ของคุณเป็น:
<application
android:name=".MyApplication"
...
จากนั้นคุณสามารถเรียกสิ่งนี้จากกิจกรรมใด ๆ และบันทึกวัตถุลงในApplication
คลาส
ในกิจกรรมแรก:
MyObject myObject = new MyObject();
MyApplication app = (MyApplication) getApplication();
app.setMyObject(myObject);
ในกิจกรรมที่สองให้ทำ:
MyApplication app = (MyApplication) getApplication();
MyObject retrievedObject = app.getMyObject(myObject);
สิ่งนี้มีประโยชน์ถ้าคุณมีวัตถุที่มีขอบเขตระดับแอปพลิเคชันนั่นคือจะต้องใช้งานตลอดทั้งแอปพลิเคชัน Parcelable
วิธีการยังคงดีกว่าถ้าคุณต้องการการควบคุมที่ชัดเจนกว่าขอบเขตวัตถุหรือถ้าขอบเขตที่มี จำกัด
สิ่งนี้หลีกเลี่ยงการใช้งานIntents
โดยสิ้นเชิง ฉันไม่รู้ว่าพวกเขาเหมาะสมกับคุณหรือไม่ อีกวิธีหนึ่งที่ฉันใช้คือการมีint
ตัวระบุของวัตถุที่ส่งผ่านความตั้งใจและดึงวัตถุที่ฉันมีในแผนที่ในApplication
วัตถุ
Map
ที่เก็บวัตถุและดึงข้อมูลโดยใช้ตัวระบุ ปัญหาที่แท้จริงเพียงอย่างเดียวของวิธีนี้คือ Android จะล้างหน่วยความจำหลังจากผ่านไประยะหนึ่งดังนั้นคุณต้องตรวจสอบ nulls บน onResume ของคุณ (ฉันคิดว่า Objects ที่ส่งผ่าน intents นั้นยังคงอยู่ แต่ไม่แน่ใจ) นอกจากนั้นฉันไม่เห็นว่ามันด้อยกว่าอย่างมาก
ใน model class ของคุณ (Object) จะใช้ Serializable ได้เช่น:
public class MensajesProveedor implements Serializable {
private int idProveedor;
public MensajesProveedor() {
}
public int getIdProveedor() {
return idProveedor;
}
public void setIdProveedor(int idProveedor) {
this.idProveedor = idProveedor;
}
}
และกิจกรรมแรกของคุณ
MensajeProveedor mp = new MensajeProveedor();
Intent i = new Intent(getApplicationContext(), NewActivity.class);
i.putExtra("mensajes",mp);
startActivity(i);
และกิจกรรมที่สองของคุณ (กิจกรรมใหม่)
MensajesProveedor mensajes = (MensajesProveedor)getIntent().getExtras().getSerializable("mensajes");
โชคดี!!
public class SharedBooking implements Parcelable{
public int account_id;
public Double betrag;
public Double betrag_effected;
public int taxType;
public int tax;
public String postingText;
public SharedBooking() {
account_id = 0;
betrag = 0.0;
betrag_effected = 0.0;
taxType = 0;
tax = 0;
postingText = "";
}
public SharedBooking(Parcel in) {
account_id = in.readInt();
betrag = in.readDouble();
betrag_effected = in.readDouble();
taxType = in.readInt();
tax = in.readInt();
postingText = in.readString();
}
public int getAccount_id() {
return account_id;
}
public void setAccount_id(int account_id) {
this.account_id = account_id;
}
public Double getBetrag() {
return betrag;
}
public void setBetrag(Double betrag) {
this.betrag = betrag;
}
public Double getBetrag_effected() {
return betrag_effected;
}
public void setBetrag_effected(Double betrag_effected) {
this.betrag_effected = betrag_effected;
}
public int getTaxType() {
return taxType;
}
public void setTaxType(int taxType) {
this.taxType = taxType;
}
public int getTax() {
return tax;
}
public void setTax(int tax) {
this.tax = tax;
}
public String getPostingText() {
return postingText;
}
public void setPostingText(String postingText) {
this.postingText = postingText;
}
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(account_id);
dest.writeDouble(betrag);
dest.writeDouble(betrag_effected);
dest.writeInt(taxType);
dest.writeInt(tax);
dest.writeString(postingText);
}
public static final Parcelable.Creator<SharedBooking> CREATOR = new Parcelable.Creator<SharedBooking>()
{
public SharedBooking createFromParcel(Parcel in)
{
return new SharedBooking(in);
}
public SharedBooking[] newArray(int size)
{
return new SharedBooking[size];
}
};
}
ผ่านข้อมูล:
Intent intent = new Intent(getApplicationContext(),YourActivity.class);
Bundle bundle = new Bundle();
i.putParcelableArrayListExtra("data", (ArrayList<? extends Parcelable>) dataList);
intent.putExtras(bundle);
startActivity(intent);
การดึงข้อมูล:
Bundle bundle = getIntent().getExtras();
dataList2 = getIntent().getExtras().getParcelableArrayList("data");
ทางออกที่ง่ายที่สุดที่ฉันพบคือ .. เพื่อสร้างคลาสที่มีสมาชิกข้อมูลคงที่พร้อมตัวตั้งค่า getters
กำหนดจากกิจกรรมหนึ่งและรับจากกิจกรรมอื่นที่คัดค้าน
กิจกรรม
mytestclass.staticfunctionSet("","",""..etc.);
กิจกรรม b
mytestclass obj= mytestclass.staticfunctionGet();
คุณสามารถใช้วิธีการ putExtra (Serializable .. ) และ getSerializableExtra () เพื่อส่งและดึงข้อมูลออบเจ็กต์ประเภทคลาสของคุณ คุณจะต้องทำเครื่องหมายคลาสของคุณเป็น Serializable และตรวจสอบให้แน่ใจว่าตัวแปรสมาชิกทั้งหมดของคุณนั้นเป็นแบบอนุกรมเช่นกัน ...
สร้างแอปพลิเคชัน Android
ไฟล์ >> ใหม่ >> แอปพลิเคชัน Android
ป้อนชื่อโครงการ: android-pass-object-to-activity
Pakcage: com.hmkcode.android
เลือกตัวเลือกค่าเริ่มต้นอื่น ๆ ไปที่ถัดไปจนกระทั่งถึงเสร็จสิ้น
ก่อนที่จะเริ่มสร้างแอพเราจำเป็นต้องสร้างคลาส POJO“ บุคคล” ซึ่งเราจะใช้ในการส่งวัตถุจากกิจกรรมหนึ่งไปยังอีกกิจกรรมหนึ่ง ขอให้สังเกตว่าชั้นจะใช้อินเตอร์เฟซ Serializable
Person.java
package com.hmkcode.android;
import java.io.Serializable;
public class Person implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
private int age;
// getters & setters....
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
สองเลย์เอาต์สำหรับสองกิจกรรม
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tvName"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:text="Name" />
<EditText
android:id="@+id/etName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10" >
<requestFocus />
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tvAge"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:text="Age" />
<EditText
android:id="@+id/etAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10" />
</LinearLayout>
<Button
android:id="@+id/btnPassObject"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Pass Object to Another Activity" />
</LinearLayout>
activity_another.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:id="@+id/tvPerson"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_gravity="center"
android:gravity="center_horizontal"
/>
</LinearLayout>
ชั้นเรียนสองกิจกรรม
1) ActivityMain.java
package com.hmkcode.android;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity implements OnClickListener {
Button btnPassObject;
EditText etName, etAge;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnPassObject = (Button) findViewById(R.id.btnPassObject);
etName = (EditText) findViewById(R.id.etName);
etAge = (EditText) findViewById(R.id.etAge);
btnPassObject.setOnClickListener(this);
}
@Override
public void onClick(View view) {
// 1. create an intent pass class name or intnet action name
Intent intent = new Intent("com.hmkcode.android.ANOTHER_ACTIVITY");
// 2. create person object
Person person = new Person();
person.setName(etName.getText().toString());
person.setAge(Integer.parseInt(etAge.getText().toString()));
// 3. put person in intent data
intent.putExtra("person", person);
// 4. start the activity
startActivity(intent);
}
}
2) AnotherActivity.java
package com.hmkcode.android;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class AnotherActivity extends Activity {
TextView tvPerson;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_another);
// 1. get passed intent
Intent intent = getIntent();
// 2. get person object from intent
Person person = (Person) intent.getSerializableExtra("person");
// 3. get reference to person textView
tvPerson = (TextView) findViewById(R.id.tvPerson);
// 4. display name & age on textView
tvPerson.setText(person.toString());
}
}
การใช้ห้องสมุด Gson ของ Google คุณสามารถส่งวัตถุไปยังกิจกรรมอื่นที่จริงแล้วเราจะแปลงวัตถุในรูปแบบของสตริง json และหลังจากผ่านไปยังกิจกรรมอื่น ๆ เราจะแปลงวัตถุเป็นเช่นนี้อีกครั้ง
ลองพิจารณาคลาสของ bean แบบนี้
public class Example {
private int id;
private String name;
public Example(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
เราจำเป็นต้องผ่านวัตถุของคลาสตัวอย่าง
Example exampleObject=new Example(1,"hello");
String jsonString = new Gson().toJson(exampleObject);
Intent nextIntent=new Intent(this,NextActivity.class);
nextIntent.putExtra("example",jsonString );
startActivity(nextIntent);
สำหรับการอ่านเราต้องทำการย้อนกลับใน NextActivity
Example defObject=new Example(-1,null);
//default value to return when example is not available
String defValue= new Gson().toJson(defObject);
String jsonString=getIntent().getExtras().getString("example",defValue);
//passed example object
Example exampleObject=new Gson().fromJson(jsonString,Example .class);
เพิ่มการพึ่งพาในระดับที่
compile 'com.google.code.gson:gson:2.6.2'
Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);
startACtivity(i);
ฉันรู้ว่ามันสายไปแล้ว แต่มันง่ายมากสิ่งที่คุณต้องทำก็คือปล่อยให้คลาสของคุณใช้ Serializable ได้
public class MyClass implements Serializable{
}
จากนั้นคุณสามารถส่งผ่านไปยังเจตนาเช่น
Intent intent=......
MyClass obje=new MyClass();
intent.putExtra("someStringHere",obje);
ที่จะได้รับมันคุณโทรง่าย
MyClass objec=(MyClass)intent.getExtra("theString");
ถ้าคุณมีคลาส singleton (fx Service) ทำหน้าที่เป็นเกตเวย์ไปยังเลเยอร์โมเดลของคุณอย่างไรก็ตามมันสามารถแก้ไขได้โดยการมีตัวแปรในคลาสนั้นพร้อมกับ getters และ setters สำหรับมัน
ในกิจกรรมที่ 1:
Intent intent = new Intent(getApplicationContext(), Activity2.class);
service.setSavedOrder(order);
startActivity(intent);
ในกิจกรรม 2:
private Service service;
private Order order;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quality);
service = Service.getInstance();
order = service.getSavedOrder();
service.setSavedOrder(null) //If you don't want to save it for the entire session of the app.
}
อยู่ในการให้บริการ:
private static Service instance;
private Service()
{
//Constructor content
}
public static Service getInstance()
{
if(instance == null)
{
instance = new Service();
}
return instance;
}
private Order savedOrder;
public Order getSavedOrder()
{
return savedOrder;
}
public void setSavedOrder(Order order)
{
this.savedOrder = order;
}
การแก้ปัญหานี้ไม่จำเป็นต้องมีการทำให้เป็นอนุกรมหรือ "บรรจุภัณฑ์" อื่น ๆ ของวัตถุที่เป็นปัญหา แต่จะมีประโยชน์ถ้าคุณใช้สถาปัตยกรรมประเภทนี้อยู่แล้ว
ไกลโดยวิธีที่ง่ายที่สุด IMHO เพื่อพัสดุวัตถุ คุณเพียงเพิ่มแท็กคำอธิบายประกอบเหนือวัตถุที่คุณต้องการทำพัสดุ
ตัวอย่างจากห้องสมุดอยู่ด้านล่างhttps://github.com/johncarl81/parceler
@Parcel
public class Example {
String name;
int age;
public Example(){ /*Required empty bean constructor*/ }
public Example(int age, String name) {
this.age = age;
this.name = name;
}
public String getName() { return name; }
public int getAge() { return age; }
}
เริ่มใช้ Parcelableในชั้นเรียนของคุณ จากนั้นผ่านวัตถุเช่นนี้
SendActivity.java
ObjectA obj = new ObjectA();
// Set values etc.
Intent i = new Intent(this, MyActivity.class);
i.putExtra("com.package.ObjectA", obj);
startActivity(i);
ReceiveActivity.java
Bundle b = getIntent().getExtras();
ObjectA obj = b.getParcelable("com.package.ObjectA");
ไม่จำเป็นต้องใช้สตริงแพ็กเกจเพียงแค่สตริงต้องเหมือนกันในทั้งสองกิจกรรม
เริ่มกิจกรรมอื่นจากกิจกรรมนี้ผ่านพารามิเตอร์ผ่านทาง Bundle Object
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "xyz@gmail.com");
startActivity(intent);
ดึงข้อมูลในกิจกรรมอื่น (YourActivity)
String s = getIntent().getStringExtra("USER_NAME");
มันก็โอเคสำหรับประเภทข้อมูลที่เรียบง่าย แต่ถ้าคุณต้องการส่งผ่านข้อมูลที่ซับซ้อนในระหว่างกิจกรรมคุณต้องทำให้เป็นอันดับแรก
ที่นี่เรามีรูปแบบพนักงาน
class Employee{
private String empId;
private int age;
print Double salary;
getters...
setters...
}
คุณสามารถใช้ Gson lib ที่จัดทำโดย google เพื่อจัดทำข้อมูลที่ซับซ้อนเช่นนี้
String strEmp = new Gson().toJson(emp);
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("EMP", strEmp);
startActivity(intent);
Bundle bundle = getIntent().getExtras();
String empStr = bundle.getString("EMP");
Gson gson = new Gson();
Type type = new TypeToken<Employee>() {
}.getType();
Employee selectedEmp = gson.fromJson(empStr, type);
ใน Koltin
เพิ่มนามสกุล kotlin ใน build.gradle ของคุณ
apply plugin: 'kotlin-android-extensions'
android {
androidExtensions {
experimental = true
}
}
จากนั้นสร้างคลาสข้อมูลของคุณเช่นนี้
@Parcelize
data class Sample(val id: Int, val name: String) : Parcelable
ผ่านวัตถุด้วยความตั้งใจ
val sample = Sample(1,"naveen")
val intent = Intent(context, YourActivity::class.java)
intent.putExtra("id", sample)
startActivity(intent)
รับวัตถุด้วยความตั้งใจ
val sample = intent.getParcelableExtra("id")
วิธีที่ง่ายที่สุดและ java คือ: ใช้ serializable ในคลาส pojo / model ของคุณ
แนะนำสำหรับ Android สำหรับมุมมองประสิทธิภาพ: สร้างแบบจำลองพัสดุได้
วิธีที่ง่ายที่สุดคือการใช้สิ่งต่อไปนี้โดยที่ไอเท็มนั้นเป็นสตริง:
intent.putextra("selected_item",item)
สำหรับการรับ:
String name = data.getStringExtra("selected_item");