文章目錄
AMF是Adobe搗鼓出來的一種開源的傳輸格式,用在多個地方,例如flash與後台傳輸,red5流媒體之類。在Adobe的BlazeDS伺服器其實已經提供了如何解析AMF的代碼,但由於耦合度有點高,因此有熱心人士從BlazeDS伺服器原始碼中將解析AMF那一部分抽了出來並放在google的程式碼程式庫裡,網址如下:http://code.google.com/p/amf-serializer/,這個類庫在Java環境下使用完全沒有問題,但在Android中使用的時候,會報一些類似於PropertyDescriptor沒找到或者解析不了的錯誤。原因在於Android1.6的JavaSDK裡貌似沒有PropertyDescriptor這個類。PropertyDescriptor是一個用於內省的類,其實裡面有一些功能我們完全可以用基本的反射來類比出來:
PropertyDescriptor
import java.lang.reflect.Method;public class PropertyDescriptor {private String name;private String displayName;private Method readMethod;private Method writeMethod;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDisplayName() {return displayName;}public void setDisplayName(String displayName) {this.displayName = displayName;}public Method getReadMethod() {return readMethod;}public void setReadMethod(Method readMethod) {this.readMethod = readMethod;}public Method getWriteMethod() {return writeMethod;}public void setWriteMethod(Method writeMethod) {this.writeMethod = writeMethod;}}
PropertyDescriptorHelper
import java.lang.reflect.Method;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class PropertyDescriptorHelper {public static List<PropertyDescriptor> getPropertyDescriptors(Class<?> type) {List<PropertyDescriptor> lsDescriptor = new ArrayList<PropertyDescriptor>();Method[] aryMethod = type.getMethods();Map<String, Method> dicMethod = new HashMap<String, Method>(); for (Method method : aryMethod) { if(method.getName().startsWith("set") && method.getParameterTypes() != null && method.getParameterTypes().length == 1) {dicMethod.put(method.getName(),method); }} for(Method method : aryMethod) { if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) {String name = Character.toLowerCase(method.getName().charAt(3)) + method.getName().substring(4, method.getName().length());PropertyDescriptor desc = new PropertyDescriptor();desc.setDisplayName(name);desc.setName(name);desc.setReadMethod(method);String setMethodName = "set" + name.substring(0,1).toUpperCase() + name.substring(1, name.length());if(dicMethod.containsKey(setMethodName)){desc.setWriteMethod(dicMethod.get(setMethodName));}lsDescriptor.add(desc);} else if (method.getName().startsWith("is") && method.getParameterTypes().length == 0) {String name = Character.toLowerCase(method.getName().charAt(2)) + method.getName().substring(3, method.getName().length());PropertyDescriptor desc = new PropertyDescriptor();desc.setDisplayName(name);desc.setName(name);desc.setReadMethod(method);String setMethodName = "set" + name.substring(0,1).toUpperCase() + name.substring(1, name.length());if(dicMethod.containsKey(setMethodName)){desc.setWriteMethod(dicMethod.get(setMethodName));}lsDescriptor.add(desc);} } return lsDescriptor;}public static List<PropertyDescriptor> getPropertyDescriptors(Object bean) {return getPropertyDescriptors(bean.getClass());}}
有了這兩個類以後,就可以尋找amf-serializer類庫中所有使用到PropertyDescriptor的地方,替換為我們寫的這兩個類,這樣解析AMF的準系統就具備了。
不過單純使用這個類庫,只是能解析AMF,但與服務端互動的功能還沒有。這個也很簡單,BlazeDS伺服器原始碼裡就有一個AMFConnection類,這個類封裝了JDK裡的HttpURLConnection類進行網路傳輸並對AMF進行序列化還原序列化,我們只需要把這個抽出來修改一下就可以用。
順便提一下,AMF其實是支援多個方法調用的,原理就是在一個AMFMessage裡添加多個AMFBody,每一個AMFBody就是一個方法調用,但AMFConnection預設並不支援多個方法調用,大家參考AMFConnection類裡的call方法自行添加即可。
完整的demo請到這裡下載:http://download.csdn.net/detail/visualcatsharp/4294746
沒資源分的請留下郵箱。