【问题标题】:Passing Parcelable object which has a member variable which is Not parcelable(a class that belongs to third party library)传递具有不可包裹成员变量的可包裹对象(属于第三方库的类)
【发布时间】:2019-10-22 04:56:51
【问题描述】:

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

主活动:

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

虚拟 Parcelable 类:

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

【问题讨论】:

  • 检查类是否实现可序列化,如果是,则使您的类可序列化并继续。
  • 该类不实现可序列化或可打包。而且我们也不能更改,因为它属于第三方库。
  • 在这种情况下,在您的应用程序类中使用静态方法来设置和获取您的数据对象,例如:stackoverflow.com/a/56273846/5571700

标签: android parcelable parcel


【解决方案1】:

如果无法实现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())。不要忘记在清单中引用您的子类Application,如here 所述。开始服务前:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-30
    • 2014-02-12
    • 2019-01-31
    相关资源
    最近更新 更多