我正在尝试从一个“活动”发送客户类的对象,并在另一个“”中显示它。
客户类别的代码:
public class Customer {
private String firstName, lastName, address;
int age;
public Customer(String fname, String lname, int age, String address) {
firstName = fname;
lastName = lname;
age = age;
address = address;
}
public String printValues() {
String data = null;
data = "First Name :" + firstName + " Last Name :" + lastName
+ " Age : " + age + " Address : " + address;
return data;
}
}
我想将其对象从一个“活动”发送到另一个“,然后在另一个活动”上显示数据。
我怎样才能做到这一点?
我一直想知道为什么这不能像调用其他活动的方法一样简单。我最近写了一个实用程序库,使它几乎如此简单。你可以在这里查看(https://github.com/noxiouswinter/gnlib_android/wiki/gnlauncher).
GNLauncher使从另一个“活动”等向“活动”发送对象/数据变得简单,就像调用该“活动”中的一个函数并将所需数据作为参数一样。它引入了类型安全性,并消除了所有必须串行化、使用字符串键附加到意图以及在另一端撤消的麻烦。
用法
使用要在要启动的“活动”上调用的方法定义接口。
public interface IPayload {
public void sayHello(String name, int age);
}
在要启动的“活动”上实现上述界面。当活动准备就绪时,也通知GNLauncher。
public class Activity_1 extends Activity implements IPayload {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Notify GNLauncher when the Activity is ready.
GNLauncher.get().ping(this);
}
@Override
public void sayHello(String name, int age) {
Log.d("gnlib_test", "Hello " + name + "! \nYour age is: " + age);
}
}
在另一个“活动”中,获取上述“活动”的代理,并使用所需参数调用任何方法。
public class Activity_2 extends Activity {
public void onClick(View v) {
((IPayload)GNLauncher.get().getProxy(this, IPayload.class, Activity_1.class)).sayHello(name, age);
}
}
将启动第一个活动,并使用所需参数调用方法。
先决条件
请参阅https://github.com/noxiouswinter/gnlib_android/wiki#prerequisites有关如何添加依赖项的信息。
你可以尝试使用该类。限制是它不能在一个过程之外使用。
一项活动:
final Object obj1 = new Object();
final Intent in = new Intent();
in.putExtra(EXTRA_TEST, new Sharable(obj1));
其他活动:
final Sharable s = in.getExtras().getParcelable(EXTRA_TEST);
final Object obj2 = s.obj();
public final class Sharable implements Parcelable {
private Object mObject;
public static final Parcelable.Creator < Sharable > CREATOR = new Parcelable.Creator < Sharable > () {
public Sharable createFromParcel(Parcel in ) {
return new Sharable( in );
}
@Override
public Sharable[] newArray(int size) {
return new Sharable[size];
}
};
public Sharable(final Object obj) {
mObject = obj;
}
public Sharable(Parcel in ) {
readFromParcel( in );
}
Object obj() {
return mObject;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(final Parcel out, int flags) {
final long val = SystemClock.elapsedRealtime();
out.writeLong(val);
put(val, mObject);
}
private void readFromParcel(final Parcel in ) {
final long val = in .readLong();
mObject = get(val);
}
/////
private static final HashMap < Long, Object > sSharableMap = new HashMap < Long, Object > (3);
synchronized private static void put(long key, final Object obj) {
sSharableMap.put(key, obj);
}
synchronized private static Object get(long key) {
return sSharableMap.remove(key);
}
}
我使用parcelable将数据从一个活动发送到另一个活动。这是我的代码,在我的项目中运行良好。
public class Channel implements Serializable, Parcelable {
/** */
private static final long serialVersionUID = 4861597073026532544L;
private String cid;
private String uniqueID;
private String name;
private String logo;
private String thumb;
/**
* @return The cid
*/
public String getCid() {
return cid;
}
/**
* @param cid
* The cid to set
*/
public void setCid(String cid) {
this.cid = cid;
}
/**
* @return The uniqueID
*/
public String getUniqueID() {
return uniqueID;
}
/**
* @param uniqueID
* The uniqueID to set
*/
public void setUniqueID(String uniqueID) {
this.uniqueID = uniqueID;
}
/**
* @return The name
*/
public String getName() {
return name;
}
/**
* @param name
* The name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the logo
*/
public String getLogo() {
return logo;
}
/**
* @param logo
* The logo to set
*/
public void setLogo(String logo) {
this.logo = logo;
}
/**
* @return the thumb
*/
public String getThumb() {
return thumb;
}
/**
* @param thumb
* The thumb to set
*/
public void setThumb(String thumb) {
this.thumb = thumb;
}
public Channel(Parcel in) {
super();
readFromParcel(in);
}
public static final Parcelable.Creator<Channel> CREATOR = new Parcelable.Creator<Channel>() {
public Channel createFromParcel(Parcel in) {
return new Channel(in);
}
public Channel[] newArray(int size) {
return new Channel[size];
}
};
public void readFromParcel(Parcel in) {
String[] result = new String[5];
in.readStringArray(result);
this.cid = result[0];
this.uniqueID = result[1];
this.name = result[2];
this.logo = result[3];
this.thumb = result[4];
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] { this.cid, this.uniqueID,
this.name, this.logo, this.thumb});
}
}
在活动A中,如下所示:
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("channel",(ArrayList<Channel>) channels);
Intent intent = new Intent(ActivityA.this,ActivityB.class);
intent.putExtras(bundle);
startActivity(intent);
在ActivityB中,使用如下方法获取数据:
Bundle getBundle = this.getIntent().getExtras();
List<Channel> channelsList = getBundle.getParcelableArrayList("channel");
Android活动对象可以被销毁和重建。因此,您需要使用另一种方法来查看它们或它们创建的任何对象!!!-向上的也就是说,您可以作为静态类引用传递,但对象句柄(Java调用这些“引用”,SmallTalk也是如此;但它们不是C或汇编意义上的引用)稍后可能会无效,因为Android OE的一个“特性”是任何活动都可以在稍后被销毁和重新构建。
最初的问题是“如何在Android中将对象从一个活动传递到另一个活动”,但没有人回答这个问题。当然,您可以序列化(Serializable、Parcelable、to/from JSON)并传递对象数据的副本,这样就可以创建具有相同数据的新对象;但它将不具有相同的引用/句柄。此外,许多其他人提到可以将引用存储在静态存储中。除非Android决定开启销毁您的活动,否则这将起作用。
因此,要真正解决原始问题,您需要一个静态查找,再加上每个对象将在重新创建时更新其引用。例如,如果调用其onCreate,则每个Android活动将重新列出自己。您还可以看到一些人如何使用任务列表按名称搜索“活动”。(系统正在临时销毁此活动实例以节省空间。getRunningTasks,任务列表实际上是每个活动的最新对象实例的专门列表)。
供参考:
停止:该活动被另一个活动完全遮挡(该活动现在位于“后台”)。已停止的活动也仍然活动(活动对象保留在内存中,它维护所有状态和成员信息,但未附加到窗口管理器)。但是,用户不再能看到它,当其他地方需要内存时,系统可能会将其关闭销毁“系统正在临时销毁此活动实例以节省空间。”
因此,消息总线是一个可行的解决方案。它基本上是“双关语”。而不是试图引用对象;然后重新构建设计,使用MessagePassing而不是SequentialCode。调试难度成倍增加;但它让你忽略了这些对操作环境的理解。实际上,每个对象方法访问都是反向的,因此调用者发布一条消息,而对象本身定义了该消息的处理程序。更多的代码,但可以使其在Android OE限制下更加健壮。
如果你想要的只是顶部的“活动”(由于到处都需要“上下文”,所以在Android应用程序中很常见),那么只要调用onResume,你就可以让每个“活动”在静态全局空间中将自己列为“顶部”。然后,AlertDialog或任何需要上下文的东西都可以从那里获取它。此外,使用全局有点讨厌,但可以简化到处上下传递上下文,当然,当您使用MessageBus时,IT无论如何都是全局的。
使用gson将对象转换为JSON并通过intent传递。在新的Activity中,将JSON转换为对象。
在build.gradle中,将其添加到依赖项中
implementation 'com.google.code.gson:gson:2.8.4'
在“活动”中,将对象转换为json字符串:
Gson gson = new Gson();
String myJson = gson.toJson(vp);
intent.putExtra("myjson", myjson);
在接收活动中,将json字符串转换回原始对象:
Gson gson = new Gson();
YourObject ob = gson.fromJson(getIntent().getStringExtra("myjson"), YourObject.class);
对于Kotlin来说,这是完全一样的
传递数据
val gson = Gson()
val intent = Intent(this, YourActivity::class.java)
intent.putExtra("identifier", gson.toJson(your_object))
startActivity(intent)
接收数据
val gson = Gson()
val yourObject = gson.fromJson<YourObject>(intent.getStringExtra("identifier"), YourObject::class.java)