【问题标题】:How to extend android class which implements Parcelable interface?如何扩展实现 Parcelable 接口的 android 类?
【发布时间】:2013-07-17 13:01:35
【问题描述】:

首先我检查了this answer

我想要做的是扩展 Location 类调用它 LocationPlus 有一些 成员变量。我想要实现的功能是将LocationPlus 类的对象从一个活动传递到另一个活动。

这是我的CREATOR

public static final Parcelable.Creator<LocationPlus> CREATOR = new Parcelable.Creator<LocationPlus>() {
    @Override 
    public LocationPlus createFromParcel(Parcel source) {
        return new LocationPlus(source);
    }
    @Override 
    public LocationPlus[] newArray(int size) {
        return new LocationPlus[size];
    }
};

我面临的问题是这个错误

Implicit super constructor Location() is undefined. Must explicitly invoke another constructor

尝试编写构造函数时

public LocationPlus(Parcel in) {

有人在评论中让我发布 LocationPlus 课程,所以这里是

public class LocationPlus extends Location{

    private int mBattery = -1;

    public LocationPlus(String locationName) {
        super(locationName);
    }

    public LocationPlus(Location location) {
        super(location);
    }

    public int getmBattery() {
        return mBattery;
    }

    public void setmBattery(int mBattery) {
        this.mBattery = mBattery;
    }
    @Override
    public int describeContents() {
        return 0;
    }

    public static final Parcelable.Creator<LocationPlus> CREATOR = new Parcelable.Creator<LocationPlus>() {
        @Override 
        public LocationPlus createFromParcel(Parcel source) {
            return new LocationPlus(source);
        }
        @Override 
        public LocationPlus[] newArray(int size) {
            return new LocationPlus[size];
        }
    };

    @Override
    public void writeToParcel(Parcel out, int flags) {
        super.writeToParcel(out, flags);
        out.writeInt(mBattery);
    }

    public LocationPlus(Parcel in) {
        mBattery =in.readInt();
    }
}

【问题讨论】:

  • 发布您的 LocationPlus 课程
  • @Hasslarn 代码已发布。
  • 只是好奇,如果你在 LocationPlus 中放置一个空的构造函数(尝试为空的和使用 super 调用)会说明什么:public LocationPlus() { super() }。我在这台机器上没有 Java,所以很遗憾我无法尝试。位置构造函数可能受到保护。
  • @Hasslarn 不幸的是,问题是父类没有空的构造函数
  • 啊..,LocationPlus(Parcel in)中的super(this)呢?

标签: android inheritance android-location


【解决方案1】:

Parcelable,速度之王

根据 google engineers 的说法,这段代码的运行速度会明显加快。造成这种情况的原因之一是我们明确了序列化过程,而不是使用反射来推断它。也有理由为此目的对代码进行了大量优化。

public abstract class BaseClass implements Parcelable {

    public String FullName;
    public boolean IsValidUser;
    public String UserName;


    public BaseClass () {
    }


    protected BaseClass(Parcel in) {
        FullName = in.readString();
        IsValidUser = in.readByte() != 0;
        UserName = in.readString();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(FullName);
        dest.writeByte((byte) (IsValidUser ? 1 : 0));
        dest.writeString(UserName);
    }
}

使用list添加到parcelable对象的子类如下:

public class DerivedClass extends BaseClass {

    public boolean IsSuccess;
    public String Message;
    public List<AnotherClass> AnotherClassObj;


    public DerivedClass () {
        super();
    }

    protected DerivedClass(Parcel in) {
        super(in);
        AnotherClassObj = new ArrayList<AnotherClass>();
        IsSuccess = in.readByte() != 0;
        Message = in.readString();
        AnotherClassObj = in.readArrayList(AnotherClass.class.getClassLoader());
    }

    public static final Creator<DerivedClass> CREATOR = new Creator<DerivedClass>() {
        @Override
        public DerivedClass createFromParcel(Parcel in) {
            return new DerivedClass(in);
        }

        @Override
        public DerivedClass[] newArray(int size) {
            return new DerivedClass[size];
        }
    };

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeByte((byte) (IsSuccess ? 1 : 0));
        dest.writeString(Message);
        dest.writeList(AnotherClassObj);
    }

    public int describeContents() {
        return 0;
    }
}

另一个类:

public class AnotherClass extends BaseClass {
    public AnotherClass() {
        super();
    }

    protected AnotherClass(Parcel in) {
        super(in);
    }

    public int describeContents() {
        return 0;
    }

    public static final Creator<AnotherClass> CREATOR = new Creator<AnotherClass>() {
        @Override
        public AnotherClass createFromParcel(Parcel in) {
            return new AnotherClass(in);
        }

        @Override
        public AnotherClass[] newArray(int size) {
            return new AnotherClass[size];
        }
    };

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
    }
}

活动中

 Intent intent = new Intent(LoginActivity.this, MainActivity.class);
 intent.putExtra("UserObject", parcelableObject);
 startActivity(intent);
 finish();

在接收活动中:

Bundle extras = getIntent().getExtras();
 if (extras != null) {
      userObject = extras.getParcelable("UserObject");
 }

【讨论】:

  • 为什么没有在基类中创建Creator?请解释。 public static final Creator&lt;BaseClass&gt; CREATOR = new Creator&lt;BaseClass&gt;()
  • @MuhammadSaqib CREATOR 对象用于从 Parcel 生成 Parcelable 类的实例。由于BaseClass 是抽象的,它不能被实例化。顺便说一句,当基类和子类都可以实例化为Parcel 时要小心。当您在写作和阅读过程中将它们混合在一起时,就会发生不好的事情。请参阅此处了解更多信息:idlesun.blogspot.com/2012/12/…
【解决方案2】:

您好,我对此进行了很多研究,但找不到任何有用的东西。我尝试下面的解决方案,它对我有用。

假设您的超类只有名为“mData”的 int 变量。

public class Location implements Parcelable {
 protected int mData;

 public int describeContents() {
     return 0;
 }

 public void writeToParcel(Parcel out, int flags) {
     out.writeInt(mData);
 }

 public static final Parcelable.Creator<Location> CREATOR
         = new Parcelable.Creator<Location>() {
     public Location createFromParcel(Parcel in) {
         return new Location(in);
     }

     public Location[] newArray(int size) {
         return new Location[size];
     }
 };

 private Location(Parcel in) {
     mData = in.readInt();
 }

}

然后,您的扩展类只有名为“mBattery”的 int 变量。

public class LocationPlus extends Location {
 protected int mBattery;

 public int describeContents() {
     return 0;
 }

 public void writeToParcel(Parcel out, int flags) {
     out.writeInt(mBattery);
 }

 public static final Parcelable.Creator<LocationPlus> CREATOR
         = new Parcelable.Creator<LocationPlus>() {
     public LocationPlus createFromParcel(Parcel in) {
         return new LocationPlus(in);
     }

     public LocationPlus[] newArray(int size) {
         return new LocationPlus[size];
     }
 };

 private LocationPlus(Parcel in) {
     mBattery = in.readInt();
 }

}

到目前为止,LocationPlus 运行良好。但是我们没有设置超类的变量。首先,我使用 super(..) 方法在扩展类上设置超类的变量。但它没有用。

private LocationPlus(Parcel in) {
     super(in);
     mBattery = in.readInt();
 }

您应该明确设置所有超类的变量,而不是上面的代码。超类的变量应该受到保护。最终的构造函数应该是这样的:

private LocationPlus(Parcel in) {
     mData = in.readIn();
     mBattery = in.readInt();
 }

而 writeToParcel 方法应该是这样的:

public void writeToParcel(Parcel out, int flags) {
     out.writeIn(mData);
     out.writeInt(mBattery);
 }

【讨论】:

  • 在 LocationPlus 构造函数中执行 super(in) 应该可以工作,您只需要确保在 writeToParcel 中也执行 super.writeToParcel(out, flags)。
【解决方案3】:

试试这个解决方案:

public static final Parcelable.Creator<LocationPlus> CREATOR =
    new Parcelable.Creator<LocationPlus>() {
    @Override
    public LocationPlus createFromParcel(Parcel in) {

        Location l = Location.CREATOR.createFromParcel(in);
        LocationPlus lp = new LocationPlus(l);

        lp.mBattery= in.readInt();

        return lp;
    }

    @Override
    public LocationPlus[] newArray(int size) {
        return new LocationPlus[size];
    }
};

@Override
public void writeToParcel(Parcel parcel, int flags) {
    super.writeToParcel(parcel, flags);
    parcel.writeInt(mBattery);

}

【讨论】:

    【解决方案4】:

    根据 Android 文档,Location 类没有 Location() 构造函数。初始化LocationPlus 类时,您需要调用super(String provider)super(Location l)

    编辑:更正语法

    (见Location Android Doc

    【讨论】:

    • 感谢您宝贵的时间和回答布赖恩我已经看过我正在寻找解决此问题的任何解决方法的文档。
    • 您需要做的是在LocationPlus(Parcel in) 方法中包含对super(String provider)super(Location l) 构造函数的调用。
    猜你喜欢
    • 2012-06-06
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 2016-04-28
    相关资源
    最近更新 更多