Invoking Gson toJson and fromJson with-in the Android application.

Gson.fromJson does not currently work in this application with proguard enabled: The reason seems to be that Cart's field List<LineItem> gets rewritten as raw List type.
This commit is contained in:
Inderjeet Singh 2011-07-23 01:08:34 +00:00
parent ea4cfcd4b9
commit a85807818f
5 changed files with 205 additions and 146 deletions

View File

@ -1,144 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.code.gson</groupId>
<artifactId>android-proguard-example</artifactId>
<packaging>apk</packaging>
<version>1.0-SNAPSHOT</version>
<name>android-proguard-example</name>
<url>http://code.google.com/p/google-gson/trunk/examples/android</url>
<description>An example illustrating using Gson and Progaurd in an Android application</description>
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>5</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<android.sdk.path>${env.ANDROID_HOME}/</android.sdk.path>
</properties>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<connection>scm:svn:http://google-gson.googlecode.com/svn/trunk/examples/android</connection>
<developerConnection>scm:svn:https://google-gson.googlecode.com/svn/trunk/examples/android</developerConnection>
<url>http://google-gson.codegoogle.com/trunk/examples/android</url>
</scm>
<issueManagement>
<system>Google Code Issue Tracking</system>
<url>http://code.google.com/p/google-gson/issues/list</url>
</issueManagement>
<dependencies>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>android</artifactId>
<version>1.5_r4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>1.8-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>maven-android-plugin</artifactId>
<version>2.9.0-beta-4</version>
<configuration>
<sdk>
<path>${env.ANDROID_HOME}/</path>
<platform>1.5</platform>
</sdk>
<deleteConflictingFiles>true</deleteConflictingFiles>
</configuration>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
<workspace>../../eclipse-ws</workspace>
<workspaceCodeStylesURL>
file:///${basedir}/../lib/formatting-styles.xml
</workspaceCodeStylesURL>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<links>
<link>http://download.oracle.com/javase/1.5.0/docs/api/</link>
</links>
<version>true</version>
<show>public</show>
</configuration>
</plugin>
</plugins>
</build>
<developers>
<developer>
<name>Inderjeet Singh</name>
</developer>
</developers>
</project>

View File

@ -1,3 +1,4 @@
##---------------Begin: proguard configuration common for all Android apps ----------
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
@ -14,6 +15,7 @@
-keepattributes *Annotation*
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
-repackageclasses ''
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
@ -61,9 +63,21 @@
public static ** valueOf(java.lang.String);
}
-keep public class * {
public protected *;
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
##---------------End: proguard configuration common for all Android apps ----------
##---------------Begin: proguard configuration for Gson ----------
# Gson specific classes
-keep class sun.misc.Unsafe.** { *; }
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
##---------------End: proguard configuration for Gson ----------

View File

@ -15,10 +15,17 @@
*/
package com.google.gson.examples.android;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import com.google.gson.Gson;
import com.google.gson.examples.android.model.Cart;
import com.google.gson.examples.android.model.LineItem;
/**
* Activity class illustrating how to use proguard with Gson
*
@ -30,7 +37,24 @@ public class GsonProguardExampleActivity extends Activity {
super.onCreate(icicle);
setContentView(R.layout.main);
TextView tv = (TextView) findViewById(R.id.tv);
tv.setText("Hello World");
Gson gson = new Gson();
Cart cart = buildCart();
StringBuilder sb = new StringBuilder();
sb.append("Gson.toJson() example: \n");
sb.append(" Cart Object: ").append(cart).append("\n");
sb.append(" Cart JSON: ").append(gson.toJson(cart)).append("\n");
sb.append("\n\nGson.fromJson() example: \n");
String json = "{buyer:'Happy Camper',creditCard:'4111-1111-1111-1111',"
+ "lineItems:[{name:'nails',priceInMicros:100000,quantity:100,currencyCode:'USD'}]}";
sb.append("Cart JSON: ").append(json).append("\n");
sb.append("Cart Object: ").append(gson.fromJson(json, Cart.class)).append("\n");
tv.setText(sb.toString());
tv.invalidate();
}
private Cart buildCart() {
List<LineItem> lineItems = new ArrayList<LineItem>();
lineItems.add(new LineItem("hammer", 1, 12000000, "USD"));
return new Cart(lineItems, "Happy Buyer", "4111-1111-1111-1111");
}
}

View File

@ -0,0 +1,108 @@
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.gson.examples.android.model;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.List;
import com.google.gson.annotations.SerializedName;
/**
* A model object representing a cart that can be posted to an order-processing server
*
* @author Inderjeet Singh
*/
public class Cart {
public final List<LineItem> lineItems;
@SerializedName("buyer")
private final String buyerName;
private final String creditCard;
public Cart(List<LineItem> lineItems, String buyerName, String creditCard) {
this.lineItems = lineItems;
this.buyerName = buyerName;
this.creditCard = creditCard;
}
public List<LineItem> getLineItems() {
return lineItems;
}
public String getBuyerName() {
return buyerName;
}
public String getCreditCard() {
return creditCard;
}
@Override
public String toString() {
StringBuilder itemsText = new StringBuilder();
boolean first = true;
if (lineItems != null) {
try {
Class<?> fieldType = Cart.class.getField("lineItems").getType();
System.out.println("LineItems CLASS: " + getSimpleTypeName(fieldType));
} catch (SecurityException e) {
} catch (NoSuchFieldException e) {
}
for (LineItem item : lineItems) {
if (first) {
first = false;
} else {
itemsText.append("; ");
}
itemsText.append(item);
}
}
return "[BUYER: " + buyerName + "; CC: " + creditCard + "; "
+ "LINE_ITEMS: " + itemsText.toString() + "]";
}
@SuppressWarnings("unchecked")
public static String getSimpleTypeName(Type type) {
if (type == null) {
return "null";
}
if (type instanceof Class) {
return ((Class)type).getSimpleName();
} else if (type instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType) type;
StringBuilder sb = new StringBuilder(getSimpleTypeName(pType.getRawType()));
sb.append('<');
boolean first = true;
for (Type argumentType : pType.getActualTypeArguments()) {
if (first) {
first = false;
} else {
sb.append(',');
}
sb.append(getSimpleTypeName(argumentType));
}
sb.append('>');
return sb.toString();
} else if (type instanceof WildcardType) {
return "?";
}
return type.toString();
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.gson.examples.android.model;
/**
* A line item in a cart. This is not a rest resource, just a dependent object
*
* @author Inderjeet Singh
*/
public class LineItem {
private final String name;
private final int quantity;
private final long priceInMicros;
private final String currencyCode;
public LineItem(String name, int quantity, long priceInMicros, String currencyCode) {
this.name = name;
this.quantity = quantity;
this.priceInMicros = priceInMicros;
this.currencyCode = currencyCode;
}
public String getName() {
return name;
}
public int getQuantity() {
return quantity;
}
public long getPriceInMicros() {
return priceInMicros;
}
public String getCurrencyCode() {
return currencyCode;
}
@Override
public String toString() {
return String.format("(item: %s, qty: %s, price: %.2f %s)",
name, quantity, priceInMicros/(double)1000000, currencyCode);
}
}