tags:

views:

421

answers:

1

I have a class (below) that I want to send to a Service Class through an Intent. I have implemented the Parcelable interface but am unsure how to actually send and retrieve the entire object including the current state of the object.

In particular

@Override 
public void writeToParcel(Parcel dest, int flags) {
      //I need this to send the entire state of the object
}

And

public UrlParamsHelper(Parcel in) {
    //I need this to unpack the state of the object
}

Here is the actual class

/*
  * A holder class for URL parameters
  */
 public static class UrlParamsHelper implements Parcelable {
  private final HttpClient httpClient;
  private final HttpParams params = new BasicHttpParams();
  private final SchemeRegistry registry = new SchemeRegistry();
  private final ThreadSafeClientConnManager manager;
  private final Uri.Builder uri = new Uri.Builder();
  final HttpHost host;

  final String urlPath;
  final String hostname;
  /*
   * @param hostname the hostname ie. http://www.google.com
   * @param urlPath the path to the file of interest ie. /getfiles.php
   */
  public  UrlParamsHelper(final String hostname, final String urlPath) {
   HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
   HttpProtocolParams.setContentCharset(params, "UTF-8");
   registry.register(new Scheme("http",PlainSocketFactory.getSocketFactory(), 80));
   manager = new ThreadSafeClientConnManager(params, registry);
   httpClient = new DefaultHttpClient(manager, params);
   host = new HttpHost(hostname, 80, "http");
   uri.path(urlPath);

   this.urlPath = urlPath;
   this.hostname = hostname;
  }

  public UrlParamsHelper(Parcel in) {
   //unpack the state
  }

  public void addQueryString(String key, String value) {
   uri.appendQueryParameter(key, value);
  }

  public HttpGet buildGetQuery() {
   return new HttpGet(uri.build().toString());
  }

  public HttpClient getHttpClient() {
   return httpClient;
  }

  public HttpHost getHttpHost() {
   return host;
  } 

  @Override
  public int describeContents() {
   return 0;
  }

  @Override
  public void writeToParcel(Parcel dest, int flags) {
   //Parcel the entire state of the object
  }

  //Constructs the parcel again - REQUIRED
      public static final Parcelable.Creator<UrlParamsHelper> CREATOR = new Parcelable.Creator<UrlParamsHelper>() {
       public UrlParamsHelper createFromParcel(Parcel in) {
           return new UrlParamsHelper(in);
       }

       public UrlParamsHelper[] newArray(int size) {
        throw new UnsupportedOperationException();
           //return new UrlParamsHelper[size];
       }
   };
 }
+1  A: 

In your writeToParcel function, you need to write which state objects you want to the Parcel, for instance:

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

It doesn't matter which order you write the objects, so long as you read them back in in the same order:

@Override
public UrlParamsHelper(Parcel in) {
    urlPath = in.readString();
    hostname = in.readString();
}

The problem is that you can only read and write the object types mentioned in the documentation for Parcel, so it may be difficult to save absolutely everything.

synic
The problem is that I have already added a number of QueryStrings via addQueryString. This method does not preserve those values.
jax
Well I got it working but I had to modify it a little to make the class more clumsy, instead of directly adding the query string parameters I instead make a local Map that hold key value pairs, I then serialize this map and send it over to the service. When the Service calls buildGetQuery() the entire map get put into the Uri using a for loop. All in all this seems like a lot of work for sending such a simple object. Does anyone know if there is a better way?
jax
Perhaps you could make a wrapper for Uri.Builder that makes it also Parcelable. Then you could use something like dest.writeParcelable(uri). I know this doesn't make it more simple, it just helps you break it into logical blocks. The simple fact is that you can't save anything but primitive types and other Parcelables to a Parcel, so AFAIK, there isn't a simpler way to do it.
synic