How to add Java Socket object to Parcelable in Android - java

I want to pass a Java Socket object from one activity to another. I thought of using Parcelable for passing but cannot add the object to the parcel
public class NetworkInformation implements Parcelable {
private String ipAddress;
private String portNo;
private Socket networkSocket;
protected NetworkInformation(Parcel in) {
}
public static final Creator<NetworkInformation> CREATOR = new Creator<NetworkInformation>() {
#Override
public NetworkInformation createFromParcel(Parcel in) {
return new NetworkInformation(in);
}
#Override
public NetworkInformation[] newArray(int size) {
return new NetworkInformation[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(ipAddress);
dest.writeString(portNo);
//How to add the Socket to parcelable here ?
}
}

I'm not sure if this will work, but you might try:
private String ipAddress;
private String portNo;
private Socket networkSocket;
protected NetworkInformation(Parcel in) {
ipAddress = in.readString();
portNo = in.readString();
networkSocket = new Socket(makeRealIP(ipAddress),makeRealPortNo(portNo));
}
Of course, you would have to write your own makeRealIP and makeRealPortNo to convert the strings back into useful parameters for a new Socket();
Bundle myBundle = new Bundle();
NetworkInformation myNetworkInfo;
myBundle.putParceable("myNetworkInfo",myNetworkInfo);
myNetworkInfo = (NetworkInformation)myBundle.getParceable("myNetworkInfo");
I've not tried this, and I'll bet the other folks that answered were quite correct to warn about mucking around at the socket layer. It can get a bit tricky. Good Luck.

Related

Unable to create POJO with Retrofit and Java in android

I am getting following json response from one of the vendor.
{
"status": "success",
"data": {
"values": [
[
"2015-12-28T09:15:00+0530",
1386.4,
1388,
1381.05,
1385.1,
788
],
[
"2015-12-28T09:15:00+0530",
1386.4,
1388,
1381.05,
1385.1,
788
]
]
}
}
I would like to convert this to POJO.
I am using retrofit 2.0, rx java.
I have tried following
public class HistoricalDataContainer implements Parcelable{
public String status;
public CandleList data;
protected HistoricalDataContainer(Parcel in) {
status = in.readString();
data = in.readParcelable(CandleList.class.getClassLoader());
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(status);
dest.writeParcelable(data, flags);
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<HistoricalDataContainer> CREATOR = new Creator<HistoricalDataContainer>() {
#Override
public HistoricalDataContainer createFromParcel(Parcel in) {
return new HistoricalDataContainer(in);
}
#Override
public HistoricalDataContainer[] newArray(int size) {
return new HistoricalDataContainer[size];
}
};
}
And
public class CandleList implements Parcelable{
public ArrayList<ArrayList<String>> values = new ArrayList<>();// doesn't work
public ArrayList<String[]> values=new ArrayList<String[]>();// doesn't work
public ArrayList<String>[] values; // doesn't work
protected CandleList(Parcel in) {
}
#Override
public void writeToParcel(Parcel dest, int flags) {
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<CandleList> CREATOR = new Creator<CandleList>() {
#Override
public CandleList createFromParcel(Parcel in) {
return new CandleList(in);
}
#Override
public CandleList[] newArray(int size) {
return new CandleList[size];
}
};
}
But in the above code "value" is always null.
What am I missing.
You are missing the annotations style for Gson.
For example:
public class LiveStreamResponse extends BaseResponse{
#SerializedName("live_stream")
#Expose
private LiveStream liveStream;
#SerializedName("meta")
#Expose
private Meta meta;
public LiveStream getLiveStream() {
return liveStream;
}
public void setLiveStream(LiveStream liveStream) {
this.liveStream = liveStream;
}
public Meta getMeta() {
return meta;
}
public void setMeta(Meta meta) {
this.meta = meta;
}
}
That help Retrofit to match with all objects on your POJO, you have to define which object have to be matched with your "status": "success", "data", "values" from the Json File.
You can read more about following this tutorial. Consuming APIs with Retrofit
And also I give you this example using xml and Json.
First you need to identify the objects that are in the JSON structure, in this case there are two.1. The json that you are receiving and 2. data .
The option is to create a class for every object.
the first class contains the main object (json itself) with his main attributes: status and data.
public class HistoricalDataContainer implements Parcelable {
private string status;
private Data data;
setters - getters
...
}
data is an object, so you need to create his own class to handle his attributes, in this case is an array with string arrays
public class Data implements Parcelable {
private List<String> values;
setters - getters
...
}
To get an specific array inside values you are going to do something like:
List<String> myStringArray = historicalDataContainer.getData().values().get(index);
AND
Why are you using Parcelable?
...
I hope this answer is what you need!
You can try http://www.jsonschema2pojo.org/ for JSON Mapping. It's a great tool for creating models from existing JSON responses. And for quick implementation of Parcelable to existing class you can use http://www.parcelabler.com/

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

Parcelable class with exception as attribute (Android)

I want to send an object from an activity to another using Parcelable in the class. I have a Parcelable class that has two strings and an Exception as attributes.
public class ReportErrorVO implements Parcelable {
private String titleError;
private String descriptionError;
private Exception exceptionError;
public ReporteErrorVO(Parcel in) {
titleError = in.readString();
descriptionError = in.readString();
exceptionError = ????; //What do I put here?
}
public ReporteErrorVO() {
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(titleError);
dest.writeString(descriptionError);
dest.writeException(exceptionError);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public ReportErrorVO createFromParcel(Parcel in) {
return new ReportErrorVO(in);
}
public ReportErrorVO[] newArray(int size) {
return new ReportErrorVO[size];
}
};
#Override
public int describeContents() {
return 0;
}
//Getter and setters atributes...
}
What can I do to set the exception in the parcelable attribute?
You can use readException method in.readException() and this method will throw the exception if it had been written to the parcel, so you may catch it and save to your variable.
try {
in.readException();
} catch (Exception e){
exceptionError = e;
}
Note that this method only supports limited types of exceptions
The supported exception types are:
* BadParcelableException
* IllegalArgumentException
* IllegalStateException
* NullPointerException
* SecurityException
* NetworkOnMainThreadException
Ok, doing it this way helped me to get things working: Send the exception on an array.
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mTitleError);
dest.writeString(mDescriptionError);
Exception[] exceptions = new Exception[1];
exceptions[0] = mExceptionError;
dest.writeArray(exceptions);
}
public ReportErrorVO(Parcel in) {
mTitleError = in.readString();
mDescriptionError = in.readString();
Object[] exceptions = in.readArray(Exception.class.getClassLoader());
mExceptionError = (Exception) exceptions[0];
}

Using Parceable to pass Objects in android

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

Parcelling complex objects b/w activities in android

I have a complex class "Class11" containing Socket,PrintWriter class references.
I am getting exception while trying to pass it between activities.
public interface Interface11 extends Parcelable{
...........
}
public class Class11 implements Interface11 {
Socket clientSocket;
ServerSocket serverSocket;
PrintWriter writer;
BufferedReader reader;
private JChatConnection(Parcel in) {
Object [] objects= in.readArray(Object.class.getClassLoader());
clientSocket=(Socket) objects[0];
serverSocket=(ServerSocket) objects[1];
writer=(PrintWriter) objects[2];
reader=(BufferedReader) objects[3];
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
Object objects[] = new Object[4];
objects[0]=clientSocket;
objects[1]=serverSocket;
objects[2]=writer;
objects[3]=reader;
dest.writeArray(objects);
}
public static final Parcelable.Creator<Class11> CREATOR =
new Parcelable.Creator<Class11>() {
public Class11 createFromParcel(Parcel in) {
return new Class11(in);
}
public Class11[] newArray(int size) {
return new Class11[size];
}
};
};
though i have option of sharing it via static object reference,
but to reduce coupling i tried to pass it via intent,
& i got exception:
java.lang.RuntimeException: unable to marshall value Socket[address=/192.168.43.225,port=9990,localport=213234]
at android.os.Parcel.writeValue(Parcel.java:1137)
at android.os.Parcel.writeArray(Parcel.java: 543)........
is it because Socket ,PrintWriter are not parcellable or,
am i messing this code at writeToParcel() and private Class11(Parcel in)
anybody has idea that how to pass this object between activities ?
I suggest not pass your object instance as an argument to Activity. Make it a Singleton, or a member of Application class. That will allow you to access Class11 instance everywhere in your app.

Categories