如何在android中的onResponse方法之外访问响应值

时间:2017-01-30 02:35:03

标签: java android asynchronous android-volley

我正在开发一个Android项目。我得到了谷歌api的回复并解析了json。但我想在onResponse方法之外返回值,这对我来说似乎是不可能的。以下是我的代码,我已在此处看到此answer。但我想在这个异步方法之外的这个值。是否可以访问此值。

更新 - 我已更新了我的代码以获取更多详细信息。这是我的完整活动课程。你可以看到我想要达到的目标。请帮助我如何在方法onResponse中的方法get_time_to_travel中访问Volley parseJson返回的值。这真的让我很伤心。我的第一个Android项目,我在最近两天被困在这里。

对此有任何帮助将不胜感激。

public class MainActivity extends AppCompatActivity {


    private RecyclerView recyclerView;
    private LinearLayoutManager linearLayoutManager;
    private CustomAdapter adapter;
    private List<UserData> userData;
    private LocationManager locationManager;
    private LocationListener locationListener;
    String origin, mode = "driving";
    private String API = "APIKey";
    TextView textView;
    RequestQueue requestQueue;
    RequestQueue requestQueue1;
    String url = "https://url/users";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        recyclerView.setHasFixedSize(true);


        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                double lat = location.getLatitude();
                double lng = location.getLongitude();
                origin = String.valueOf(lat)+","+String.valueOf(lng);
            }

            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {

            }

            @Override
            public void onProviderEnabled(String provider) {

            }

            @Override
            public void onProviderDisabled(String provider) {
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(intent);
            }
        };
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION,
                        Manifest.permission.INTERNET
                }, 10);
            }
            return;
        }
        else{
            locationManager.requestLocationUpdates("gps", 5000, 0, locationListener);
        }


        getData();

        linearLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);
        adapter = new CustomAdapter(this, userData);
        recyclerView.setAdapter(adapter);

    }

    private void getData(){
        userData = new ArrayList<>();
        requestQueue = Volley.newRequestQueue(this);

        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(url,
                new Response.Listener<JSONArray>() {

                    @Override
                    public void onResponse(JSONArray response) {
                        parseJson(response);
                    }
                },

                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.e("VOLLEY", "ERROR");
                    }
                }
        );
        requestQueue.add(jsonArrayRequest);
    }

    private void parseJson(JSONArray response){
        try {
            for (int i = 0; i < response.length(); i++) {
                JSONObject users = response.getJSONObject(i);

                String id = ("id: "+users.getString("id"));
                String name = ("Name: "+users.getString("name"));
                String username = ("Username: "+users.getString("username"));
                String email = ("Email: "+users.getString("email"));
                String address = parseAddress(users);
                String destination = parseCoordinates(users);
                String company = parseCompany(users);
                String phone = ("Phone: "+users.getString("phone"));
                String website = ("Website: "+users.getString("website"));
                String eta = get_time_to_travel(origin, destination, API, mode);

                UserData udata = new UserData(id, name, username, email, address, phone, website, company,eta);
                userData.add(udata);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }


    private String parseAddress(JSONObject users) {
        JSONObject completeAdd = null;
        String address = null;
        try {
            completeAdd = users.getJSONObject("address");
            String street = completeAdd.getString("street");
            String suite = completeAdd.getString("suite");
            String city = completeAdd.getString("city");
            String zipcode = completeAdd.getString("zipcode");
            address = ("Address :" + street + ", " + suite + ", " + city + ", " + zipcode);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return address;
    }

    private String parseCoordinates(JSONObject users) {
        JSONObject completeAdd = null;
        String destination = null;
        try {
            completeAdd = users.getJSONObject("address");
            JSONObject coordinates = completeAdd.getJSONObject("geo");
            String latitude = coordinates.getString("lat");
            String longitude = coordinates.getString("lng");
            destination = latitude + "," + longitude;
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return destination;
    }

    private String parseCompany(JSONObject users) {
        JSONObject companyDetail = null;
        String company = null;
        try {
            companyDetail = users.getJSONObject("company");
            String company_name = companyDetail.getString("name");
            String catchPhrase = companyDetail.getString("catchPhrase");
            String bs = companyDetail.getString("bs");
            company = ("Company: " + company_name + ", " + catchPhrase + ", " + bs);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return company;
    }


    private String get_time_to_travel(String origin, String destination, String API, String mode){
        requestQueue1 = Volley.newRequestQueue(this);
        String eta = null;
        String google_api = "https://maps.googleapis.com/maps/api/distancematrix/json?origins="+origin+"&destinations="
                +destination+"s&mode="+mode+"&language=fr-FR&key="+API;
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, google_api, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        eta = parseGoogleData(response);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.e("VOLLEY", "ERROR");
                    }
                }

        );
        requestQueue1.add(jsonObjectRequest);
        return eta;
    }

    private String parseGoogleData(JSONObject response) {
        String estimated_time_arrival = null;
        try {
            JSONArray rows = response.getJSONArray("rows");

            JSONObject elements = rows.getJSONObject(0);
            JSONArray elementsArr = elements.getJSONArray("elements");

            JSONObject durationObj = elementsArr.getJSONObject(0);
            JSONObject durationData = durationObj.getJSONObject("duration");
            estimated_time_arrival = durationData.getString("text");

        } catch (JSONException e) {
            e.printStackTrace();
        }
        return estimated_time_arrival;
    }

}

4 个答案:

答案 0 :(得分:2)

异步任务正在其他线程上工作。因此,如果您想要访问该方法的任何变量,您需要等到任务完成。否则变量将为null。 例如:on on response method

@Override
        public void onResponse(String response) {
            res=response;
            anyMethodtopassVar(DataType data);
        }

答案 1 :(得分:1)

在活动OnCreate()中,删除这2行

adapter = new CustomAdapter(this, userData);
recyclerView.setAdapter(adapter);

getData()中删除此行

userData = new ArrayList<>();

将它们放在parseJson()中,如下所示:

private void parseJson(JSONArray response){
    try {

        if(userData==null){
            userData = new ArrayList<>();
        }else{
            userData.clear();
        }
        for (int i = 0; i < response.length(); i++) {
            JSONObject users = response.getJSONObject(i);

            String id = ("id: "+users.getString("id"));
            String name = ("Name: "+users.getString("name"));
            String username = ("Username: "+users.getString("username"));
            String email = ("Email: "+users.getString("email"));
            String address = parseAddress(users);
            String destination = parseCoordinates(users);
            String company = parseCompany(users);
            String phone = ("Phone: "+users.getString("phone"));
            String website = ("Website: "+users.getString("website"));
            String eta = get_time_to_travel(origin, destination, API, mode);

            UserData udata = new UserData(id, name, username, email, address, phone, website, company,eta);
            userData.add(udata);
        }

        if(adapter == null){
            adapter = new CustomAdapter(this, userData);
            recyclerView.setAdapter(adapter);
        }else{
            adapter.notifyDataSetChanged();
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

这样,当json调用完成时,调用parseJson()。 在将数组解析为userData后,适配器将被初始化或通知。

修改

嗯,这不是最好的解决方案。但它只是我头脑中的东西 有点讨厌/肮脏。我不知道,但我认为它会完成这项工作

1-您不必每次都重新启动队列,因此在get_time_to_travel()中将该行放在方法之外:

requestQueue1 = Volley.newRequestQueue(this);

final int index param添加到方法并将其设为void

private void get_time_to_travel(String origin, String destination, String API, String mode, final int index){...

在方法中生成onResponse(),如下所示:

public void onResponse(JSONObject response) {
    eta = parseGoogleData(response);
    userData.get(index).setEta(eta);//add this setter to your data object if not exist.
}

删除 return eta;

现在使用空字符串初始化udata为eta

UserData udata = new UserData(id, name, username, email, address, phone, website, company,"");
userData.add(udata);

修改get_time_to_travel()parseJson()的来电,如下所示:

get_time_to_travel(origin, destination, API, mode, i);

get_time_to_travel()调用onResponse()时,对象将被修改为保存从API检索的eta

这很讨厌,有时候adapter可能会在完成对 google api 的所有通话之前得到通知。所以这只是为了告诉你如何制作它

<强> EDIT2 解决方法就是这样 init userData对象,带标签&#34;正在加载......&#34;对于eta

UserData udata = new UserData(id, name, username, email, address, phone, website, company,"Loading...");

并在onResponse()的{​​{1}}结束时通知适配器:

get_time_to_travel()

答案 2 :(得分:0)

您想在parseJson内获得onResponse的结果吗? 将parseJson的返回类型更改为UserData,在try块内调用return userDate;,在catch块中调用return null;。这将帮助您从调用它的位置捕获parseJson的结果。 如果我没有正确理解你的问题,请告诉我。

答案 3 :(得分:-1)

public void getString(final VolleyCallback callback) {
    StringRequest req = new StringRequest(Request.Method.GET, url, new     Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            res=response;
            callback.onSuccess(res);
        }
    }...
}}

public interface VolleyCallback{
    void onSuccess(String result);
}

现在在你的主要活动中,你可以这样做。

public void onResume(){
super.onResume();
getString(new VolleyCallback(){
     @Override
     public void onSuccess(String res){
         ... //do something
     }
});

}