應用phprpc協議實現Android用戶端的一些總結
本來這篇文章會放Android版本做完就寫的~結果由於一系列的事情而耽擱掉了,下面是我在使用phprpc協議編寫android應用時出現的問題的一些心得總結。
?
1、登陸機制及用戶端同步問題
服務端是由phprpc提供的遠程調用介面,當然首先要開啟android的互連網存取權限:
?
?
?在AndroidManifest.xml插入以上語句,哎。。。這個語句害小弟查了半天啊。。。程式編好居然一直沒法顯示內容一查才知道少了這個許可權,打死我也不會忘了它~~
?
接著因為服務端用的是會話儲存HashCode形式的登入驗證模式。就是說在用戶端中一直公用同一個用戶端對象和HashCode,在Android不能像Web應用一樣使用Session或Cookie跨頁面全域變數,如以前有一篇我寫的博文寫的可以用Android內建的全域對象。建立如下代碼:
?
import org.phprpc.PHPRPC_Client;import android.app.Application;public class ShareContext extends Application {private PHPRPC_Client client = null;private String source = null;public String getSource() {return source;}public void setSource(String source) {this.source = source;}public PHPRPC_Client getClient() {return client;}public void setClient(PHPRPC_Client client) {this.client = client;}}
?
?上面就是公用的用戶端對象和HashCode,並在AndroidManifest.xml中更改下列代碼:
?
?
?上面的android:name=".ShareContext"這句話就是聲明一個context上下文全域變數,再詳細的參見那篇博文。
初次登陸初始化內容物件:
?
shareContext = ((ShareContext)getApplicationContext());this.client = shareContext.getClient();this.source = shareContext.getSource();if(this.client == null){Intent it = getIntent(); String accountStr = it.getStringExtra("accountStr").toString(); String passwordStr = it.getStringExtra("passwordStr").toString(); this.client = new PHPRPC_Client(SERVICE_URL); this.client.setEncryptMode(2); this.source = Cast.toString(client.invoke("check_login", new Object[]{accountStr,passwordStr})); if(this.source == null){ Log.e("flowg_error", "source not find!"); Toast.makeText(getApplicationContext(), "驗證錯誤",Toast.LENGTH_SHORT).show(); }else{ client.useService(SERVICE_URL); shareContext.setClient(this.client); shareContext.setSource(this.source); } Object s = client.invoke("selfuser_timeline", new Object[]{source,0,20});Log.v("source0",s.toString()); }
?
?之後就可以在其他Activity中取出內容物件中這兩個屬性了:
?
shareContext = ((ShareContext)getApplicationContext()); client = shareContext.getClient(); source = shareContext.getSource();
?在其後就能正式的使用它們了。
?
?
2、關於遠程調用傳輸的數組序列化問題
在phprpc中雖然傳輸的是php編譯化hash碼,但用戶端調用後回調中的一般會轉化為現有系統無法識別的數組,對於php服務端傳輸過了是一個索引數組,而在java端是沒有索引數組這一說的,準確是一個經過處理的HashMap,剛開始還不知道phprpc庫有提供數組序列化解析庫,一直取不出裡面的值(協議庫相當不錯,但api文檔做的貌似差了點),搞phprpc就是看源碼來弄,api什麼的只是入個門,在看源碼時候發現有AssocArray這樣一個庫內建索引數組類。。。好吧,繼續。。。
現在問題就解決了,看下面代碼:
?
this.list = new ArrayList();AssocArray alist = (AssocArray)client.invoke("home_timeline", new Object[]{this.source,0,20});for(int i = 0 ; i < alist.size();++i){AssocArray a = (AssocArray)alist.get(i);TopicInfo ti = new TopicInfo();ti.setNickname(Cast.toString(a.get("nickname")));ti.setUid(Cast.toString(a.get("uid")));ti.setCreateTime(Cast.toString(a.get("create_time")));ti.setAvatar(Cast.toString(a.get("avatar")));ti.setContent(Cast.toString(FunctionUtil.Html2Text(Cast.toString(a.get("content")))));this.list.add(ti);}
在對於invoke遠程調用時返回數組直接格式化為AssocArray類,接下來就能像使用HashMap一樣使用get方法取出資料了,這個索引數組類並不是繼承HashMap,而是將HashMap作為內部屬性
,就是說phprpc庫對LinkedHashMap鏈式HashMap做了一層外層封裝,裡面的方法基本和HashMap差不多,具體可以看源碼。
?
3、遠程調用字串的格式化
這個問題貌似在網上有很多人提問。。。看了這個api文檔真的得修正修正了,其實分析了源檔案源碼後會發現原來phprpc還是提供解析類,這個類就是Cast,
直接調用下面的靜態方法便可以搞定:
?
Cast.toString(a.get("nickname"));
?
小結:感覺phprpc的api文檔真的做的不咋的。。有待完善,害得我有問題就要看庫源碼,不過感覺android平台下使用phprpc應該和java下沒有什麼區別,剛開始的xml配置丟失搞的我很懊惱啊,而其中的格式化數組字串什麼的也折騰了好久。。。善哉善哉。。。