phprpc プロトコルを使用した Android クライアントの実装の概要
本来はAndroid版が完成したらすぐにこの記事を書く予定でしたが、色々あって遅れてしまいました phprpcを使用した際に発生した問題をいくつか紹介します。 Android アプリケーションを作成するためのプロトコルの体験の概要。
?
1. ログインメカニズムとクライアント同期の問題
サーバーは phprpc が提供するリモート呼び出しインターフェイスです。もちろん、最初に Android のインターネット アクセスを有効にする必要があります。
?
<uses-permission android:name="android.permission.INTERNET" />
?
? 上記のステートメントを AndroidManifest.xml に挿入します。 。 。この一文を見て、私は長い間確認させられました。 。 。プログラムを作成した後、まだコンテンツを表示できません。確認したところ、この権限は死んでも忘れません~~
。?
サーバーはセッション保存ハッシュコードの形式でログイン検証モードを使用するためです。つまり、同じクライアント オブジェクトと HashCode がクライアント内で常に共有されます。たとえば、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 内の次のコードを変更します。
?
<application android:name=".ShareContext" android:icon="@drawable/icon" android:label="@string/app_name">
?
? 上記の文 android:name=".ShareContext" はコンテキスト グローバル変数を宣言しています。詳細については、そのブログ投稿を参照してください。
初期ログイン コンテキスト オブジェクト:
?
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()); }
?
? その後、他のアクティビティのコンテキスト オブジェクトからこれら 2 つの属性を取り出すことができます。
?
shareContext = ((ShareContext)getApplicationContext()); client = shareContext.getClient(); source = shareContext.getSource();
? 後で正式に使用できます。
?
?
2. リモート呼び出しの送信に関する配列のシリアル化の問題
PHP でコンパイルされたハッシュ コードは phprpc で送信されますが、クライアントが呼び出した後のコールバックは、通常、既存のシステムでは認識できない配列に変換されます。送信されたインデックス配列。Java 側にはインデックス配列のようなものはありません。これはまさに処理された HashMap です。最初は、phprpc ライブラリが配列シリアル化解析ライブラリを提供していることを知りませんでした。内部の値を取得できませんでした (プロトコル ライブラリは非常に優れていますが、API ドキュメントは少し貧弱なようです)。ソースコードを調べてみると、インデックス配列クラスが付属する AssocArray のようなライブラリがあることがわかりました。 。 。はい、どうぞ。 。 。
これで問題は解決しました。次のコードを見てください:
?
this.list = new ArrayList<TopicInfo>(); 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); }
リモート呼び出しを行うと、返された配列は AssocArray クラスに直接フォーマットされ、HashMap を使用するのと同じように get メソッドを使用してデータを取得できます。このインデックス配列クラスは HashMap を継承しません。ただし、内部プロパティとして HashMap を使用します
、つまり、phprpc ライブラリには、LinkedHashMap チェーンされた HashMap のパッケージ化の外側の層があります。詳細については、ソース コードを参照してください。
?
3. リモート呼び出し文字列のフォーマット
この質問は、オンラインで多くの人から寄せられているようです。 。 。この API ドキュメントを読んだ後、実際に修正する必要があります。実際、ソース コードを分析したところ、phprpc は依然としてこのクラス
を提供していることがわかりました。次の静的メソッドを呼び出すだけです:
?
Cast.toString(a.get("nickname"));
?
要約: phprpc の API ドキュメントは本当に良くないと感じます。 。改善する必要があるので、問題が発生した場合はライブラリのソースコードを確認する必要がありますが、Android プラットフォームで phprpc を使用するのは Java を使用するのと同じであるはずで、xml の設定に非常に腹を立てました。が最初に失われ、その中のフォーマットされた配列文字列が失われ、どうすればよいかを理解するのに長い時間がかかりました。 。 。いい、いい、いい。 。 。