Using Parceable to pass Objects in android - java

Wrote a class that helps pass my object, was working fine until i wanted to pass a more generic object myself.
public class StepParceble implements Parcelable {
private Step mStep;
private JSONObject mStepData;
private onScreen mOnScreen;
public StepParceble(Step step, JSONObject stepData, onScreen onScreen) {
setmStep(step);
setmStepData(stepData);
setmOnScreen(onScreen);
}
public StepParceble(Parcel parcel){
}
public onScreen getmOnScreen() {
return mOnScreen;
}
public void setmOnScreen(onScreen mOnScreen) {
this.mOnScreen = mOnScreen;
}
public void setmStep(Step mStep) {
this.mStep = mStep;
}
public void setmStepData(JSONObject mStepData) {
this.mStepData = mStepData;
}
public JSONObject getmStepData() {
return mStepData;
}
public Step getmStep() {
return mStep;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
try {
dest.writeArray(new Object[]{mStep, mStepData,mOnScreen});
} catch (Exception e) {
}
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public StepParceble createFromParcel(Parcel in) {
return new StepParceble(in);
}
public StepParceble[] newArray(int size) {
return new StepParceble[size];
}
};
}
it return a null pointer on getting any of those values.
Passing the data as
StepParceble stepParceble = new StepParceble(step, stepData, onScreen);
Intent uiIntent = new Intent(context, UIActivity.class).putExtra(UiControlTrier.STEP_KEY,stepParceble);

You didn't provide means to read fields from your parcelable when you've overridden the constructor
public StepParceble(Parcel parcel){
//add methods to populate fields from parcel
}
You can use Android Studio plugins to do this for you:
https://github.com/mcharmas/android-parcelable-intellij-plugin
Also, if your class has complex-type fields (like Step in your case), those should be Parcelable too

Related

why there is a null parameter in the constructor when decompile the Parcelable class in android studio

The source is like this :
public class NavUIStatus implements Parcelable {
public static final Creator<NavUIStatus> CREATOR = new
Creator<NavUIStatus()
{
public NavUIStatus createFromParcel(Parcel in) {
return new NavUIStatus(in);
}
public NavUIStatus[] newArray(int size) {
return new NavUIStatus[size];
}
};
private NavUIStatus(Parcel in){
...
in.readTypedList(this.laneInfos, LaneInfo.CREATOR);
}
}
and when decompile this class in the android studio, the class is shown as this:
public class NavUIStatus implements Parcelable {
public static final Creator<NavUIStatus> CREATOR = new Creator() {
public NavUIStatus createFromParcel(Parcel in) {
return new NavUIStatus(in, null);
}
public NavUIStatus[] newArray(int size) {
return new NavUIStatus[size];
}
};
}
so, why there is null parameter in the NavUIStatus(in, null) ?
thanks.

Strategy pattern with inner enum

I'm trying to get rid of big switch statement from my code and I thought that Strategy pattern based on my existing enum would be nice. The concept is like:
public class MyStrategy {
public MyStrategy() {
Option.Option1.setMethodToExecute(this::action1);
Option.Option2.setMethodToExecute(this::action2);
}
public void executeChoosenMethod(int i) {
Option.values()[i].execute();
// instead of
// switch(convertItoOption()) {
// case Option1:...
// case Option2:...
// }
}
private void action1() {
System.out.println("action1");
}
private void action2() {
System.out.println("action2");
}
private enum Option {
Option1, Option2;
private InvokeAction methodToExecute;
public void setMethodToExecute(InvokeAction methodToExecute) {
this.methodToExecute = methodToExecute;
}
public void execute() {
methodToExecute.execute();
}
}
#FunctionalInterface
private interface InvokeAction {
void execute();
}
}
so I can use it like:
public class StrategyTest {
public static void main(String[] args) {
MyStrategy strategy = new MyStrategy();
//user choose 0 or 1
strategy.executeChoosenMethod(0);
strategy.executeChoosenMethod(1);
}
}
but I don't like this part with Option.Option1.setMethodToExecute(this::action1); since my enum has more and more options and I would like to have all of this inside enum. What would be perfect is something like this:
public class MyStrategy {
public void executeChoosenMethod(int i) {
Option.values()[i].execute();
}
private void action1() {
System.out.println("action1");
}
private void action2() {
System.out.println("action2");
}
private enum Option {
Option1(MyStrategy.this::action1),
Option2(MyStrategy.this::action2);
private InvokeAction methodToExecute;
private Option(InvokeAction method) {
methodToExecute = method;
}
public void execute() {
methodToExecute.execute();
}
}
#FunctionalInterface
private interface InvokeAction {
void execute();
}
}
but this is impossible since enum is static and I don't have access to enclosing instance by MyStrategy.this. I need enum, because I have set of options and it is convenient to use methods like values() or valueOf(), but what I would like to have is single line invoke instead of growing switch.
Do you have any ideas how to achieve sometghing like this or is there any workaround to make this enum constructor call possible Option1(MyStrategy.this::action1) ?
With enums you could implement it like this:
public class MyStrategy {
public void executeChoosenMethod(int i) {
Option.values()[i].execute(this);
}
private void action1() {
System.out.println("action1");
}
private void action2() {
System.out.println("action2");
}
private enum Option {
Option1(MyStrategy::action1),
Option2(MyStrategy::action2);
private InvokeAction methodToExecute;
private Option(InvokeAction method) {
methodToExecute = method;
}
public void execute(MyStrategy s) {
methodToExecute.execute(s);
}
}
#FunctionalInterface
private interface InvokeAction {
void execute(MyStrategy s);
}
}
This uses the fact the with lambdas you can make method references to arbitrary instance methods and call them on a specific instance by passing in the instance as first parameter.
you're right. This isn't possible with enum. But why not just use a good old class:
public class MyStrategy {
public MyStrategy() {
buildUp();
}
public void executeChoosenMethod(int i) {
actions.get(i).execute();
}
private void action1() {
System.out.println("action1");
}
private void action2() {
System.out.println("action2");
}
private List<InvokeAction> actions = new ArrayList<>();
private void buildUp() {
actions.add(this::action1);
actions.add(this::action2);
}
#FunctionalInterface
private interface InvokeAction {
void execute();
}
}

Parcel: unable to marshal value org.jivesoftware.smack.tcp.XMPPTCPConnection

I am very beginner in Android and Parcelable interface . I just want to send
private XMPPTCPConnection xmpptcpConnection;
this above XMPPTCPConnection object from one Activity to another Activity.But I am error getting error as:
java.lang.RuntimeException: Parcel: unable to marshal value org.jivesoftware.smack.tcp.XMPPTCPConnection#342f1d60
at android.os.Parcel.writeValue(Parcel.java:1337)
at com.example.rahul.samplesmack.Def.writeToParcel(Def.java:31)
Below is my java code:
public class Def implements Parcelable {
private XMPPTCPConnection xmpptcpConnection;
public void setXmpptcpConnection(XMPPTCPConnection xmpptcpConnection)
{
this.xmpptcpConnection = xmpptcpConnection;
}
public XMPPTCPConnection getXmpptcpConnection()
{
return xmpptcpConnection;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeValue(xmpptcpConnection); //I am getting Error here!!!!!
}
public Def(){}
protected Def(Parcel in) {
xmpptcpConnection = (XMPPTCPConnection) in.readValue(XMPPTCPConnection.class.getClassLoader());
}
public static final Creator<Def> CREATOR = new Creator<Def>() {
#Override
public Def createFromParcel(Parcel in) {
return new Def(in);
}
#Override
public Def[] newArray(int size) {
return new Def[size];
}
};
}

Create Enum with list of the same object

I would like to create an enum containing one attribut, a list of objects extending the same interface or the same abstract class.
The objective is to have a loop on each list of my enum to call methods dynamically.
public interface Regles {
void verifier();
}
public class Regle01 implements Regles {
#Override
public void verifier() {
}
}
public class Regle02 implements Regles {
#Override
public void verifier() {
}
}
public enum ListRegles {
ENUM1(Arrays.asList(new Regle01(), new Regle02())),
ENUM2(Arrays.asList(new Regle01()))
private List<Regles> regles = new ArrayList<Regles>();
ListRegles(List<Regles> r) {
regles = r;
}
}
how can i do this please ?
enum:
public enum ListRegles {
ENUM1(new Regle01(),new Regle02()),
ENUM2(new Regle01());
private List<Regles> regles ;
ListRegles(Regles... regles) {
this.regles = new ArrayList<>(Arrays.asList(regles));
}
public void verify() {
for (Regles regle : regles) {
regle.verifier();
}
}
}
Will call verifier for Regle01 and Regle02
ListRegles.ENUM1.verify();

Storing Methods in an Enum? [duplicate]

This question already has an answer here:
Methods in Enums [duplicate]
(1 answer)
Closed 8 years ago.
Right now, I have an enum for a variety of values, and I was wondering if there is any way I would be able to store a method in an enum. For example:
public enum myEnum{
one("first", callFirstMethod),
two("second", callSecondMethod),
three("last", callThirdMethod);
public String message;
public Method met;
myEnum(String m, Method meth){
message = m;
met = meth;
}
}
public class myMethods{
public void callFirstMethod(){
System.out.println("First!");
}
public void callSecondMethod(){
System.out.println("Second!");
}
public void callThirdMethod(){
System.out.println("Third!");
}
}
Then by using something like:
Method method = myEnum.one.callFirstMethod();
To call the method. Is something like this possible? I've tried playing around/looking around on google, and nothing is really turning up. Thank you for the help!
Use an interface and have the interface instance as the second enum parameter, or give it an abstract method that is implemented in the instance. For instance:
enum MyEnum {
ONE("first", new MyInterface() {
#Override
public void commonMethod() {
System.out.println("First!");
}
}) {
#Override
public void abstractEnumMethod() {
System.out.println("abstract enum meuthod, first!");
}
},
TWO("second", new MyInterface() {
#Override
public void commonMethod() {
System.out.println("Second!");
}
}) {
#Override
public void abstractEnumMethod() {
System.out.println("abstract enum meuthod, second!");
}
},
THREE("last", new MyInterface() {
#Override
public void commonMethod() {
System.out.println("Third!");
}
}) {
#Override
public void abstractEnumMethod() {
System.out.println("abstract enum meuthod, third!");
}
};
private String message;
private MyInterface myType;
private MyEnum(String m, MyInterface myType) {
message = m;
this.myType = myType;
}
public String getMessage() {
return message;
}
public MyInterface getMyType() {
return myType;
}
public void enumMethod() {
System.out.println(message);
}
public abstract void abstractEnumMethod();
}
interface MyInterface {
void commonMethod();
}
The answer all depends on what it's you want to achieve. For example, you could provide a common method within you enum and inspect the instance of the enum calling it...
public class TestEnum {
public static void main(String[] args) {
MyEnum.ONE.doStuff();
MyEnum.TWO.doStuff();
MyEnum.THREE.doStuff();
}
public enum MyEnum {
ONE("first"),
TWO("second"),
THREE("last");
public String message;
MyEnum(String m) {
message = m;
}
public void doStuff() {
System.out.println(name());
if (ONE.equals(this)) {
System.out.println("...Do stuff for one");
} else if (TWO.equals(this)) {
System.out.println("...Do stuff for two");
} else if (THREE.equals(this)) {
System.out.println("...Do stuff for three");
}
}
}
}
Which outputs...
one
...Do stuff for one
two
...Do stuff for two
three
...Do stuff for three

Categories