Я недавно начал для себя изучать Android и собственно java, до этого всегда писал на nodeJS, и за долгое время очень привык к js.
И вот, в процессе изучения, настал момент, когда я решил написать один единственный класс который будет отправлять запросы, и в результате ошибки или успеха будет выполнять соответствующие методы класса из которого мы и шлем этот запрос.
Есть класс MainActivity в котором по клику на кнопку шлем запрос на сервер и ответ вставляем в TextView. Сейчас я реализовал коллбэки таким образом:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
protected void onCreate(Bundle savedInstanceState) {
sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DoRequestClass doRequestClass = new DoRequestClass(){
@Override
public void onOK(JSONObject response) {
successReq(response);
}
@Override
public void onError(VolleyError error) {
errorReq(error);
}
};
doRequestClass.execute("http://myserver.local", MainActivity.this);
}
});
public void successReq(JSONObject response){
txtDisplay.setText("Response => "+response.toString());
}
public void errorReq(VolleyError error){
txtDisplay.setText("Error => "+error.toString());
}
// other methods
Такой вот для теста абстрактный класс DoRequestClass
public abstract class DoRequestClass implements DoRequestInterface {
@Override
public void execute(String url, Context context) {
RequestQueue queue = Volley.newRequestQueue(context);
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener
@Override
public void onResponse(JSONObject response) {
DoRequestClass.this.onOK(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
DoRequestClass.this.onError(error);
}
});
queue.add(jsObjRequest);
}
}
С интерфейсом DoRequestInterface
interface DoRequestInterface {
void execute(String url, Context context);
void onOK(JSONObject response);
void onError(VolleyError error);
}
Все описанное выше работает, но можно ли как-то передать successReq и errorReq в DoRequestClass таким образом, как бы мы это делали это на javascript, о то что я имею ввиду, о желанном результате, смотрите как бы я хотел примерно чтоб они передавались:
sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DoRequestClass doRequestClass = new DoRequestClass();
doRequestClass.setSuccessCallback(successReq);
doRequestClass.setErrorCallback(errorReq);
doRequestClass.execute("http://lessons.flexiblejs.ru/test.php", MainActivity.this);
}
});
Как вы поняли из кода выше, setSuccessCallback и setErrorCallback это методы которые будут говорить классу DoRequestClass какие методы класса MainActivity нужно выполнить после успешного или не успешного запроса.
Такое или подобное прекрасно работало бы в javascript'e, но такой java-код работать не будет. Вопрос в том, как создать что-то такое или приближенное к этому? И возможно ли вообще? Суть в том чтобы не писать лишний код и создавать лишнее методы типа как в моем рабочем примере onOK и onError
Прошу вас по возможности дать как можно более развернутый ответ с пояснениями, т.к. мои познания в java совсем не велики.
Ответ
Рефакторинг:
MainActivity.java
public class MainActivity extends AppCompatActivity implements
View.OnClickListener,
Response.Listener
protected void onCreate(Bundle savedInstanceState) {
((Button)findViewById(R.id.send)).setOnClickListener(this);
}
@Override
public void onClick(View v){
switch(v.getId()){
case R.id.send:
doRequestClass.execute("http://myserver.local", this, this, this);
break;
}
}
@Override
public void onResponse(JSONObject response) {
txtDisplay.setText("Response => "+response.toString());
}
@Override
public void onErrorResponse(VolleyError error) {
txtDisplay.setText("Error => "+error.toString());
}
}
DoRequestClass.java
public class DoRequestClass {
@Override
public void execute(String url, Context context, Response.Listener
На самом деле вы продублировали интерфейсы Response.Listener
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener
Для колбэков используется свой интерфейс (или несколько) и вносить в него метод execute смысла не очень много. В частности execute может быть в одном классе, а колбэк - в другом.
ЗЫ В приведенном коде есть один недочет. Вы каждый раз создаете новую очередь запросов. Так делать не стоит, для всего приложения достаточно одной очереди. Вариантов когда нужно несколько очередей, притом фиксированное количество не так много, например когда реализуется работа с несколькими акаунтами, на разные сервера слать запросы в отдельных очередях... Поэтому в классе приложения (например) стоит создать синглтон для очереди и брать ее оттуда. Либо сделать DoRequestClass (назвав его RequestManager'ом, например) синглтоном с инициализированной один раз очередью...
ЗЗЫ Еще перенес обработчик клика в активити, это по желанию "на вкус и цвет".
Комментариев нет:
Отправить комментарий