Я делаю расширение AsyncTask, которое связывается со службой с помощью различных действий и возвращает разные типы результатов в зависимости от используемого действия.У каждого действия есть слушатель, состоящий из интерфейсов, расширяющих один интерфейс с именем OnCommunicationFailedListener
.Дело в том, что я хочу иметь только одну переменную для сохранения прослушивателя типа OnCommunicationFailedListener
и сделать так, чтобы пользователь мог сохранять все «подинтерфейсы» в этой переменной.Они могут сохранять их как есть, но я не могу вызвать методы, которые вводит «подинтерфейс».
class CommunicationTask extends AsyncTask<Void, Void, String> {
private Action action;
private OnCommunicationFailedListener listener;
enum Action {
LOGIN,
LOGOUT,
SEARCH
}
interface OnCommunicationFailedListener {
void onCommunicationFailed();
}
interface OnLoginAchievedListener extends OnCommunicationFailedListener {
void onLoggedIn(String result);
void onLoginError(String error);
}
interface OnLogoutAchievedListener extends OnCommunicationFailedListener {
void onLoggedOut(String result);
void onLogoutError(String error);
}
interface OnSearchAchievedListener extends OnCommunicationFailedListener {
void onSearchAchieved(String[] results);
}
@Override protected String doInBackground(Void... voids){
try {
// Try to communicate with a query, resulting in some result.
return result;
} catch(IOException e) {
e.printStackTrace();
}
return null;
}
@Override protected void onPostExecute(String result){
super.onPostExecute(result);
if(result == null) {
listener.onCommunicationFailed();
return;
}
// ALL OF THESE GIVE ERRORS, SINCE THE METHODS DO NOT EXIST ANYMORE
switch(action){
case LOGIN:
if(<check if result is ok>){
listener.onLoggedIn(result);
} else listener.onLoginError(<some error>);
break;
case LOGOUT:
if(<check if result is ok>){
listener.onLoggedOut(result);
} else listener.onLogoutError(<some error>);
break;
case SEARCH:
String[] results = <process result>;
listener.onSearchAchieved(results);
break;
}
}
void login(String user, String password, OnLoginAchievedListener listener){
this.listener = listener;
action = Action.LOGIN;
//Build the query...
execute();
}
void logout(OnLogoutAchievedListener listener){
this.listener = listener;
action = Action.LOGOUT;
//Build the query...
execute();
}
void search(String query, OnSearchAchievedListener listener){
this.listener = listener;
action = Action.SEARCH;
//Build the query...
execute();
}
}
Идея состоит в том, что другой класс вызывает методы login()
, logout()
или search()
и дает им слушателя типа действия.Когда связь завершена и результат получен, вызываются методы слушателя действия (в моем коде это происходит в операторе switch
).
Дело в том, что эти методы не могут быть вызваны с момента передачислушатель был приведен к OnCommunicationFailedListener
.
Есть ли способ сохранить подкласс в переменной его типа суперкласса, не будучи приведенным к нему?Я не хочу иметь фактические переменные для каждого типа слушателя.