Lambda表达式返回空的android(Lambda expression returning n

2019-11-05 04:03发布

我正在写一个lambda表达式给定的纬度和经度转换为地址。 表达应该采取坐标作为参数并返回其相应的地址。 然而,返回值是零。 以下是我的课:

public class LambdaDeclarations {

String loc;

private static final String TAG = "LambdaDeclarations";

public CoordinatesToAddressInterface convert = (latitude, longitude, context) -> {
    RequestQueue queue = Volley.newRequestQueue(context);

    Log.d(TAG, "onCreate: Requesting: Lat: "+latitude+" Lon: "+longitude);
    String url ="https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins="+latitude+","+longitude+"&destinations="+latitude+","+longitude+"&key=AIzaSyCdKSW0glin4h9sGYa_3hj0L83zI0NsNRo";
    // Request a string response from the provided 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);
                    setLocation(location);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }, error -> Log.d(TAG, "onErrorResponse: That didn't work!"));
    queue.add(stringRequest);
    return getLocation();
};


public String getLocation() {
    return loc;
}

public void setLocation(String location) {
    this.loc = location;
    }
}

以下是从logcat的输出:

09-16 10:31:09.160 26525-26525/com.rmit.tejas.mad_foodtruck_2 D/LambdaDeclarations: GETRequest: JSON Object: ["77 State Route 32, West Melbourne VIC 3003, Australia"]
Location: ["77 State Route 32, West Melbourne VIC 3003, Australia"]
09-16 10:31:09.176 26525-26525/com.rmit.tejas.mad_foodtruck_2 D/LambdaDeclarations: GETRequest: JSON Object: ["111 Adderley St, West Melbourne VIC 3003, Australia"]
Location: ["111 Adderley St, West Melbourne VIC 3003, Australia"]
09-16 10:31:09.177 26525-26525/com.rmit.tejas.mad_foodtruck_2 D/LambdaDeclarations: GETRequest: JSON Object: ["4\/326 William St, Melbourne VIC 3000, Australia"]
Location: ["4\/326 William St, Melbourne VIC 3000, Australia"]

以下是我的用法:

myViewHolder.textView3.setText("Location: i->"+i+" add: "+l.convert.toAddress(trackingInfos.get(i).getLatitude(),trackingInfos.get(i).getLongitude(),context));

l是类的对象LambdaDeclarations和下面是相关的接口:

public interface CoordinatesToAddressInterface {
String toAddress(double latitude, double longitude, Context context);
}

当我试图从他们越来越正确打印相关的适配器打印的坐标。 因此,该位置得到正确设置,但是当我试图从另一个类访问它,它显示我的字符串为空值。 能否请您指教另一种方法来提取表达的位置?

Answer 1:

首先, Lambda表达式只是一个匿名类的实现,它是被用来作为一种方法或类参数和解决匿名类的遮蔽问题的设计。
所以你的情况,你不需要它了,只是简单实现CoordinatesToAddressInterface接口作为类如常。

其次,你使用的排球错了,你所提供的第一拉姆达StringRequest ,此后将呼叫响应回调,将被调用时HTTP请求完成,但return语句

return getLocation();

将空立即返回您之前setLocation(location) ,甚至你的回应回调曾经得到执行,那为什么会得到空你打电话每次convert()但你仍然可以看到日志打印,因为响应回调将被执行的(假设请求是成功)。

要正确使用响应回调,则必须更新内部回调您的UI,非常喜欢这个

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应该不是每个请求创建,因为它管理着帮助您做出更快的要求(高速缓存)内部状态,你也可以过取消请求,在像手机旋转的事件,你会得到破坏,在这种情况下,只需要调用取消方法在活动/片段的onStop()

@Override
protected void onStop () {
    super.onStop();
    if (myAdapter.getMyAdapterRequestQueue() != null) {
        myAdapter.getMyAdapterRequestQueue().cancelAll(MyAdapter.TAG);
    }
}

您取消请求后响应回调将不会被调用。



文章来源: Lambda expression returning null android