传递具有成员变量不可打包的Parcelable对象(属于第三方库的类)

时间:2019-06-06 16:17:57

标签: android parcelable parcel

我正在尝试发送一个类的对象(比如说X类的对象)作为实现Parcelable的类的一部分。 我在这里面临的问题是Class X是某些库的一部分,我无法对其进行编辑以实现Parcelable或可序列化。
我检查过Class X没有实现Parcelable或可序列化,并且我们也无法更改。
你们能帮我吗?

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);
    }
}

虚拟可包裹类:

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);
    }
}

属于另一个库的X类:

class RandomClass{
    public static int cnt = 0;
    private int nRandomNumber = 0;
    public RandomClass(int n)
    {
        nRandomNumber = n;
    }

    public int getNumb()
    {
        return nRandomNumber;
    }
}

我们需要将数据发送到的服务:

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 个答案:

答案 0 :(得分:0)

如果无法实现ParcelableSerializable,则只剩下一个选择:通过全局状态传递对象。

使用静态字段

RandomClass类型的静态字段添加到DummyParcelableObject,例如randomClassStatic。在启动服务之前进行设置:

// 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);

然后在onStartCommand()中启动服务后立即将其检索:

DummyParcelableObject obj = intent.getParcelableExtra("mObj");
obj.setRandomClass(DummyParcelableObject.randomClassStatic);
DummyParcelableObject.randomClassStatic = null;

您需要相应地定义getRandomClass()setRandomClass(),以获取/设置mRandomClass

请注意,就并发性,对象的生命周期等而言,这不是最安全的事情。

使用Application

仅当您在两端都可以访问ActivityService时,才能使用此功能。

子类Application并向其中添加类型RandomClass的字段。它将用作中继。定义用于获取/设置此字段的公共方法(例如getRandomClass()setRandomClass())。不要忘记按照清单here引用清单中的子类Application。在启动服务之前:

// 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);

然后用于在服务启动后仍在onStartCommand()中检索对象:

DummyParcelableObject obj = intent.getParcelableExtra("mObj");
obj.setRandomClass(((MyApplication) getApplication()).getRandomClass());
DummyParcelableObject.randomClassStatic = null;

这样做的好处是不使用静态字段,但是如果处理不当(线程安全性,未检查空性等),仍然可能是错误的来源。