Прежде всего, Лямбда-выражение - это просто реализация анонимного класса, она была спроектирована для использования в качестве аргумента метода или класса и для решения проблем теневого копирования анонимного класса.
Так что в вашем случае,вам это вообще не нужно, просто просто реализуйте интерфейс CoordinatesToAddressInterface
как именованный класс, как обычно.
Во-вторых, вы неправильно использовали Volley, первая лямбда, указанная вами для StringRequest
, далее будет обратным вызовом ответа на вызов, будет вызываться после завершения HTTP-запроса, но оператор возврата
return getLocation();
вернет ноль непосредственно перед тем, как ваш setLocation(location)
или даже ваш ответный обратный вызов когда-либо будет выполнен, поэтому вы получаете нулевое значение каждый раз, когда вызываете convert()
, хотя вы все равно можете видеть журнал, который вы печатаете, потому что ответный обратный вызов все равно будет выполнен(предположим, что запрос успешен).
Чтобы правильно использовать ответный обратный вызов, вы должны обновить свой пользовательский интерфейс внутри обратного вызова, примерно так:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
public static final String TAG = "MyAdapter";
private RequestQueue mQueue;
public MyAdapter(Context context) {
this.mQueue = Volley.newRequestQueue(context);
}
public RequestQueue getMyAdapterRequestQueue() {
return this.mQueue;
}
...
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, int position) {
String url ="some url";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
(String response) -> {
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray destinations = jsonObject.getJSONArray("destination_addresses");
Log.d(TAG, "GETRequest: JSON Object: "+destinations.toString());
String location = destinations.toString();
Log.d(TAG, "Location: "+location);
// update UI
holder.mTextView.setText(location);
} catch (JSONException e) {
e.printStackTrace();
}
}, error -> Log.d(TAG, "onErrorResponse: That didn't work!"));
stringRequest.setTag(TAG);
mQueue.add(stringRequest);
}
Конечно, вы можете отредактировать сигнатуру метода вашего интерфейса и заставить свой адаптер реализовать этоинтерфейс (хотя я бы предпочел сделать это таким образом), но дело в том, что вы должны обрабатывать асинхронные результаты в методе обратного вызова, никогда не ожидайте, что обратный вызов асинхронной операции завершится до ваших следующих строк кода.
RequestQueue
не следует создавать для каждого запроса, так как он управляет внутренним состоянием, которое помогает вам ускорить выполнение запроса (кэширование), вы также можете отменить запросы и в случае, например, ротации телефона, и в этом случае вы получите уничтожение,просто вызовите метод отмены в Activity / Fragment onStop()
@Override
protected void onStop () {
super.onStop();
if (myAdapter.getMyAdapterRequestQueue() != null) {
myAdapter.getMyAdapterRequestQueue().cancelAll(MyAdapter.TAG);
}
}
Ответный обратный вызов не будет вызван после отмены запроса.