Итак, я пишу приложение для Android на Java на основе приложения для iOS, над которым я также работаю, но этот вопрос больше касается того, как общаться с механизмом обратного вызова (например, с блоками в Objective-C 2.0) в Java.
Это приложение включает в себя работу в сети, аутентификацию и связь с сервером через 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, а из класса API, который можно вызвать из класса Activity, как я могу это сделать? Я легко знаю, как это сделать с блоками и делегатами в iOS, но как я могу сделать это с интерфейсами?
Например:
В iOS (используя общую сетевую структуру под названием AFNetworking) у меня есть 4 класса:
HTTPClient.ч/м
+(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];
}
ЛогинОбъект.ч/м
-(id)init
{
self = [super init];
if(self) {
[self.apiLogin loginWithSuccessBlock:^ void (NSArray *loginArray) {
//process the array
}];
}
}
ЛогинVC.ч/м
...
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, а также другой объект, поэтому я не могу использовать вторую ссылку выше, в которой вы можете указать конкретный класс, передать его и вызвать для него метод, потому что классы будут различных типов, а в Java нет универсального объекта-указателя (id или void*).