HTTP POST 経由でサーバー上にユーザー オブジェクトを作成するアプリケーションの一部に取り組んでいます。コールバック クラスの名前を文字列定数と照合する際に、非常にイライラする問題が発生しています。
環境:
このアプリケーションは約 8 ~ 10 の異なるサーバー リクエストを作成するため、実際の接続プロセスを 1 つのクラスにカプセル化しようとしましたHTTPConnection
。AndroidHttpClient
サーバーに接続する必要があるすべてのアクティビティは、 、HttpRequest
、およびの独自のインスタンスを渡しますHTTPConnectionListener
。これは、すべての呼び出しアクティビティが実装するインターフェイスであり、サーバーの応答をアクティビティに直接送り返すことができます。
応答ヘッダーを返す必要があるアプリの一部を実装する必要があるまで、これはうまく機能していました。ここまでは、 response bodyを処理するだけでよかったので HTTPConnection
、body だけを返しました。これを解決するために、コールバック クラスの名前を確認するように書き直しHTTPConnection
てから、データを要求しているクラスに応じてヘッダーまたはボディを返します。
簡単な解決策のように思えたことが、朝のかなりの時間を費やしたので、自分が間違っていることを確認するためにもっと目が必要であることに気付きました.
問題:
のコンストラクターにHTTPConnection
、(実際には を実装するすべてのものであるHTTPConnectionListener
) callbackListener を格納します。この場合、呼び出しアクティビティEditAccountActivity
はコールバックです。これを doInBackground() の早い段階でフィールドに保存して、後で確認します。
String callbackName = callbackListener.getClass().toString(); // Get the full name of the callback class and store it here.
Log.v(TAG, "** Callback listener is set to " + callbackName);
次に、接続が完了したら、定数 (最終的には定数のリスト) と照合して、応答の本文またはヘッダーを返すかどうかを判断します。
// The constant I am trying to match
final protected String EDIT_ACCOUNT = "com.example.appname.EditAccountActivity";
ボディまたはレスポンスを返すロジックは次のとおりです。
// Determine which section of response to return
if (callbackName.equals(EDIT_ACCOUNT)) {
Header responseHeader = response.getFirstHeader("Location");
return responseHeader.getValue();
} else {
return serverResponse;
}
途方もない量の Log ステートメントからわかるように、私はデバッグに成功していません。私のlogcat出力は次のようになります。
07-10 12:44:54.932: INFO/com.example.appname.ServerFetcher(21650): Entity set: HTTP.CONTENT_TYPE - application/json
07-10 12:44:54.932: VERBOSE/com.example.appname.ServerFetcher(21650): Sending user json: {"last_name":"tester ","first_name":"tester ","username":"test@testing11.com","password":"oflndveledmenkddjevhhlkh","email":"test@testing.com","profession":"tester "}
07-10 12:44:54.952: VERBOSE/com.example.appname.HTTPConnection(21650): ** Callback listener is set to class com.example.appname.EditAccountActivity
07-10 12:44:54.952: INFO/com.example.appname.HTTPConnection(21650): Executing the HTTP POST request to <url>
07-10 12:44:55.713: INFO/com.example.appname.HTTPConnection(21650): ** HTTP Response returned: 201 - CREATED
07-10 12:44:55.713: INFO/com.example.appname.HTTPConnection(21650): ** 201 - CREATED
07-10 12:44:55.713: INFO/com.example.appname.HTTPConnection(21650): Response body:
07-10 12:44:55.713: VERBOSE/com.example.appname.HTTPConnection(21650): Callback name is class com.example.appname.EditAccountActivity
07-10 12:44:55.713: VERBOSE/com.example.appname.HTTPConnection(21650): Listener is class com.example.appname.EditAccountActivity
07-10 12:44:55.713: VERBOSE/com.example.appname.HTTPConnection(21650): Are they equal? true
07-10 12:44:55.713: VERBOSE/com.example.appname.HTTPConnection(21650): EDIT_ACCOUNT constant is com.example.appname.EditAccountActivity
07-10 12:44:55.713: VERBOSE/com.example.appname.HTTPConnection(21650): Is callbackName equal to EDIT_ACCOUNT? false
07-10 12:44:55.713: VERBOSE/com.example.appname.HTTPConnection(21650): Is callbackListener.getClass().toString() equal to EDIT_ACCOUNT? false
07-10 12:44:55.723: VERBOSE/com.example.appname.EditAccountActivity(21650): onConnectionFinish called.
07-10 12:44:55.743: VERBOSE/com.example.appname.EditAccountActivity(21650): Response returned from user creation is
どういうわけか、EDIT_ACCOUNT でリスナーのクラス名を確認するたびに、同じではありません。しかし、出力を確認すると、それらはすべて私と同じように見えます。とは何も比較していません。==
すべては を使用してチェックされます.equals()
。その結果、if ステートメントの本文は実行されません。つまり、空の文字列を出力します (この特定の接続には応答本文がないため)。
続行する方法についてのアドバイスは、私の頭に髪の毛を保つのに役立ちます. 必要に応じて、クラス全体を次に示します。
HTTPConnection.java
package com.example.appname;
public class HTTPConnection extends AsyncTask<Void, Integer, String> {
final protected String TAG = HTTPConnection.class.getName();
protected AndroidHttpClient httpClient;
protected HttpRequestBase httpRequest;
protected HTTPConnectionListener callbackListener;
// Callback Class Name Constants
final protected String EDIT_ACCOUNT = "com.example.appname.EditAccountActivity";
public HTTPConnection(AndroidHttpClient httpClient, HttpRequestBase httpRequest, HTTPConnectionListener listener) {
this.httpClient = httpClient;
this.httpRequest = httpRequest;
this.callbackListener = listener;
}
@Override
protected String doInBackground(Void.. voids) {
String serverResponse = null;
String callbackName = callbackListener.getClass().toString(); // Get the full name of the callback class and store it here.
Log.v(TAG, "** Callback listener is set to " + callbackName);
try {
Log.i(TAG, "Executing the HTTP " + httpRequest.getMethod() + " request to " + httpRequest.getURI().toString());
HttpResponse response;
response = httpClient.execute(httpRequest);
// Grab the returned string as it is returned and make it a String to save memory.
StringBuilder stringBuilderResponse = inputStreamToString(response.getEntity().getContent());
serverResponse = stringBuilderResponse.toString();
// Log the response.
Log.i(TAG, "** HTTP Response returned: " + response.getStatusLine().getStatusCode() + " - " + response.getStatusLine().getReasonPhrase());
Log.i(TAG, "** Response Code: " + response.getStatusLine().getStatusCode() + " Reason Code: " + response.getStatusLine().getReasonPhrase());
Log.i(TAG, "Response body: " + serverResponse);
// ** Debug string equality **
Log.v(TAG, "Callback name is " + callbackName);
Log.v(TAG, "Listener is " + callbackListener.getClass().toString());
boolean equality1 = callbackName.equals(callbackListener.getClass().toString());
Log.v(TAG, "Are they equal? " + equality1);
Log.v(TAG, "EDIT_ACCOUNT constant is " + EDIT_ACCOUNT);
boolean equality2 = callbackName.equals(EDIT_ACCOUNT);
Log.v(TAG, "Is callbackName equal to EDIT_ACCOUNT? " + equality2);
boolean equality3 = callbackListener.getClass().toString().equals(EDIT_ACCOUNT);
Log.v(TAG, "Is callbackListener.getClass().toString() equal to EDIT_ACCOUNT? " + equality3);
// Determine which section of response to return
if (callbackName.equals(EDIT_ACCOUNT)) {
Header responseHeader = response.getFirstHeader("Location");
return responseHeader.getValue();
} else {
return serverResponse;
}
} catch (IOException e) {
Log.e(TAG, "Error when executing HTTP " + httpRequest.getMethod() + " request!");
e.printStackTrace();
return serverResponse;
}
}
@Override
protected void onPostExecute(String result) {
httpClient.close();
callbackListener.onConnectionFinish(result);
}
}
}