2

だから、私も取り組んでいる iOS アプリケーションに基づいて Java で Android アプリケーションを書いていますが、この質問は Java でコールバック メカニズム (Objective-C 2.0 のブロックなど) を通信する方法について質問しています。

このアプリケーションには、ネットワーキング、認証、および API を介したサーバーとの通信が含まれます。

私はこのフレームワークを使用しています: https://github.com/loopj/android-async-http

すべてのネットワーク モデルをクラスにカプセル化して、すべてをクリーンで簡単にしようとしています (iOS ではデリゲートとブロックを使用すると非常に簡単に見えますが、Java にはこれらの便利さがまったくないようです)。したがって、コールバックのガイドとしてこれを使用しています: http://www.gdgankara.org/2013/03/25/android-asynchronous-http-client-a-callback-based-http-client-library-for- android-and-android-smart-image-view/

ここで、Activity クラスから呼び出しを行うのではなく、Activity クラスから呼び出すことができる API クラスを呼び出したいとします。どうすればこれを行うことができますか? iOS でブロックとデリゲートを使用してこれを行う方法は簡単にわかりますが、インターフェイスでこれを行うにはどうすればよいですか?


例えば:

iOS ( AFNetworkingと呼ばれる一般的なネットワーク フレームワークを使用) には、次の 4 つのクラスがあります。

HTTPClient.h/m

+(id)sharedHTTPClient
  {
    static dispatch_once_t pred = 0;
    __strong static id __httpClient = nil;
    dispatch_once(&pred, ^{
        NSString *baseURL = http://baseurl.com;
        __httpClient = [[self alloc] initWithBaseURL:[NSURL URLWithString:baseURL]];
        [__httpClient setParameterEncoding:AFJSONParameterEncoding];        

    });
    return __httpClient;
}

APILogin.h/m

-(void)loginWithSuccessBlock:(void (^)(NSArray *responseArray))loginSuccess {
    HTTPClient *httpClient = [HTTPClient sharedHTTPClient];
    NSURLRequest *request = [httpClient requestWithMethod:@"GET" path:@"/api/login" parameters:nil];
    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        NSArray *response = [self.jsonParser parseResponseFromJSON:JSON];
        if (loginSuccess) {
            loginSuccess(response);
        }

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {  
        [APIErrorHandler handleError:error withHTTPResponse:response];
    }];

    [operation start];
}

LoginObject.h/m

-(id)init
 {
     self = [super init];
     if(self) {
         [self.apiLogin loginWithSuccessBlock:^ void (NSArray *loginArray) {
                //process the array
          }];
     }
 }

ログインVC.h/m

...
LoginObject *loginObj = [[LoginObject alloc] init];
...

したがって、これまでのところ、Android-Async-Http ライブラリを使用すると、次のようになります。

HTTPClient.java

public class HTTPClient extends AsyncHttpClient {
    public static HTTPClient sharedHTTPClient;
    public static String baseUrl = "http://baseurl.com";
    public HTTPClient {
        super();
    }
    ...
}

APILogin.java

public class APILogin {
    public void loginWithSuccessBlock() {
        HTTPClient httpClient = QHTTPClient.sharedHTTPClient;
    httpClient.get("/api/login", new JsonHttpResponseHandler() {
         @Override
         public void onSuccess(JSONArray response) {
             // Successfully got a response
            ArrayList<LoginObject> loginInfo = this.jsonParser.parseLoginFromJSON(response);
            **NEED TO DO A CALL BACK!! Like with the blocks in iOS**
         }
        @Override
         public void onSuccess(JSONObject response) {
             // Successfully got a response
            // shouldn't be an object
            throw new IllegalArgumentException();
         }


         @Override
         public void onFailure(Throwable e, String response) {
             // Response failed :(
         }
    });
}

LoginObject.java

public class LoginObject {
    public LoginObject {
        this.apiLogin.loginWithSuccessBlock(**something something for a callback**);
    }
}

うまくいけば、私が達成しようとしていることを少し明確にすることができました。成功時に、API 呼び出しを呼び出したオブジェクトである種のコールバック ブロックを実行できるようにしたいと考えています。ただし、常に同じオブジェクトであるとは限りません。LoginObject には APILogin.java のインスタンスが含まれている可能性があり、別のオブジェクトである可能性もあります。そのため、特定のクラスを指定して渡し、メソッドを呼び出すことができる上記の 2 番目のリンクは使用できません。 Java には汎用ポインター (id または void*) オブジェクトがありません。

4

1 に答える 1

1

そのため、多くのことを試し、可能な解決策をウェブで探した後、私は自分の答えを発見しました。私が思いついたのは、基本的に応答ハンドラーをチェーンすることです。

だから:

public class APILogin {
    public void loginWithSuccessBlock(**final JsonHttpResponseHandler handler**) {
        HTTPClient httpClient = QHTTPClient.sharedHTTPClient;
        httpClient.get("/api/login", handler);
    }
}

public class LoginObject {
    public LoginObject {
        this.apiLogin.loginWithSuccessBlock(new JsonHttpResponseHandler(){
        ...
        );
    }
}

多くのカスタマイズができないため、あまり堅牢ではありませんが、十分にカスタマイズできます。

于 2013-06-20T18:24:27.423 に答える