问题
I'm trying to send a class's object(let's say Class X's object) as part of class that implements Parcelable.
The problem that I am facing here is, Class X
is a part of some library and I can not edit it to implement Parcelable or serializable.
I've checked that Class X
does not implement Parcelable or serializable and we can not change as well.
Can you guys please help me here?
MainActivity:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Start the service.
DummyParcelableObject mObj = new DummyParcelableObject(new RandomClass(2019));
Intent serviceIntent = new Intent(MainActivity.this, SampleService.class);
serviceIntent.putExtra("myObj", mObj);
startService(serviceIntent);
}
}
Dummy Parcelable class:
class DummyParcelableObject implements Parcelable {
RandomClass mRandomClass;
public DummyParcelableObject(RandomClass obj) {
mRandomClass = obj;
}
protected DummyParcelableObject(Parcel in) {
mRandomClass = (RandomClass) in.readValue(RandomClass.class.getClassLoader());
}
public static final Creator<DummyParcelableObject> CREATOR = new Creator<DummyParcelableObject>() {
@Override
public DummyParcelableObject createFromParcel(Parcel in) {
return new DummyParcelableObject(in);
}
@Override
public DummyParcelableObject[] newArray(int size) {
return new DummyParcelableObject[size];
}
};
public int getRandomVar() {
int n = 0;
if (mRandomClass != null)
{
System.out.println("Anil: DummyParcelableObject: if (mRandomClass != null) is true.\n");
n = mRandomClass.getNumb();
}
else
{
System.out.println("Anil: DummyParcelableObject: if (mRandomClass != null) is false.\n");
}
return n;
}
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(mRandomClass);
}
}
Class X that is part of another library:
class RandomClass{
public static int cnt = 0;
private int nRandomNumber = 0;
public RandomClass(int n)
{
nRandomNumber = n;
}
public int getNumb()
{
return nRandomNumber;
}
}
Service that we need to send the data to:
public class SampleService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startid) {
DummyParcelableObject obj = intent.getParcelableExtra("mObj");
if (obj == null) {
System.out.println("\nAnil: ParcelableExtra is null");
}
else {
System.out.println("\nAnil: ParcelableExtra is not null");
System.out.println("\nAnil: obj.getRandomVar() = " + obj.getRandomVar());
}
return START_STICKY;
}
}
回答1:
If you cannot implement Parcelable
or Serializable
, there is only one option left: passing the object through global state.
Using static fields
Add a static field of the type RandomClass
to DummyParcelableObject
, e.g. randomClassStatic
. Set it just before starting the service:
// Start the service.
DummyParcelableObject mObj = new DummyParcelableObject(new RandomClass(2019));
Intent serviceIntent = new Intent(MainActivity.this, SampleService.class);
serviceIntent.putExtra("myObj", mObj);
DummyParcelableObject.randomClassStatic = mObj.getRandomClass();
startService(serviceIntent);
Then retrieve it right after the service started in onStartCommand()
:
DummyParcelableObject obj = intent.getParcelableExtra("mObj");
obj.setRandomClass(DummyParcelableObject.randomClassStatic);
DummyParcelableObject.randomClassStatic = null;
You would need to define getRandomClass()
and setRandomClass()
accordingly for getting / setting mRandomClass
.
Note that this is not the safest thing to do in regard of concurrency, objects' life cycles, etc…
Using the Application
class
This can only be used if you have access to an Activity
or Service
on both ends.
Subclass Application
and add a field of type RandomClass
to it. It will serves as relay. Define public methods for getting / setting this field (e.g. getRandomClass()
and setRandomClass()
). Do not forget to reference your subclassed Application
in the manifest as described here. Before starting the service:
// Start the service.
DummyParcelableObject mObj = new DummyParcelableObject(new RandomClass(2019));
Intent serviceIntent = new Intent(MainActivity.this, SampleService.class);
serviceIntent.putExtra("myObj", mObj);
((MyApplication) getApplication()).setRandomClass(mObj.getRandomClass());
startService(serviceIntent);
Then for retrieving the object once the service started, still in onStartCommand()
:
DummyParcelableObject obj = intent.getParcelableExtra("mObj");
obj.setRandomClass(((MyApplication) getApplication()).getRandomClass());
DummyParcelableObject.randomClassStatic = null;
This has the benefit of not using a static field, but can still be a source of bugs if handled poorly (thread safety, no checks on nullity, …).
来源:https://stackoverflow.com/questions/56481530/passing-parcelable-object-which-has-a-member-variable-which-is-not-parcelablea