简体   繁体   中英

execute a task after finishing another task

I have a method "getUrls" that read data from a json file in internet by volley and return a string array that contain some urls in onCreate method first I invoke this method to get urls then pass urls to my view pager adapter to download image by picasso but there is problem getUrls method is trying to download json file may string array is empty and I pass empty array to adapter so reading code should be stoped until getUrls coming finish here is my onCreate method:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_production);
    ViewPager viewPager = findViewById(R.id.view_pager);
    ArrayList<String> urls = ImageReader.getImagesUrls(this, "https://myrstcco.000webhostapp.com/productionData.json");
    PagerAdapter adapter = new ProductionViewPagerAdapter(this, urls);
}

here is getUrls method:

public static  ArrayList<String> getImagesUrls(Context context, String url) {
    final ArrayList<String> urls = new ArrayList<>();
    RequestQueue queue = Volley.newRequestQueue(context);
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    try {
                        JSONArray jsonArray = response.getJSONArray("productImagesUrl");
                        for (int i = 0; i < jsonArray.length(); i++) {
                            JSONObject item = jsonArray.getJSONObject(i);
                            urls.add(item.getString("item"));
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
        }
    });

    queue.add(request);

    return urls;
}

and here is my adapter:

public class ProductionViewPagerAdapter extends PagerAdapter {
private Context context;
private ArrayList<String> urls;

public ProductionViewPagerAdapter(Context context, ArrayList<String> urls) {
    this.context = context;
    this.urls = urls;
}

@Override
public int getCount() {
    return urls.size();
}

@Override
public boolean isViewFromObject(View view, Object object) {
    return view == object;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
    ImageView imageView = new ImageView(context);
    Picasso.with(context)
            .load(urls.get(position))
            .fit()
            .centerCrop()
            .placeholder(R.drawable.unknown_person)
            .into(imageView);
    container.addView(imageView);
    return imageView;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    container.removeView((View) object);
}

The problem is that you are not waiting the request finish, it's need to use the urls only when the request is finished

After the request is created will be needed to call it back the result

First create a callback interface

//package your.package.utils;

public interface ICallback<T>{
     void onSucess(T result);
     void onError(String error, int code);
}

Receive the callback as parameter

public static void getImagesUrls(final Context context, final String url, final ICallback<ArrayList<String>> callback) {
    RequestQueue queue = Volley.newRequestQueue(context); //Note, improve this using singleton ¹
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    try {
                        JSONArray jsonArray = response.getJSONArray("productImagesUrl");
                        ArrayList<String> urls = new ArrayList<String>();
                        for (int i = 0; i < jsonArray.length(); i++) {
                            JSONObject item = jsonArray.getJSONObject(i);
                            urls.add(item.getString("item"));
                        }
                        callback.onSucess(urls); //returns the result
                    } catch (JSONException e) {
                        e.printStackTrace();
                        callback.onError(e.toString(),0); //error with the json
                    }
                }
            }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();

            //When get a request error
            callback.onError(error.toString(),error.networkResponse.statusCode);
        }
    });

    queue.add(request);
}

After, only use the list of strings when the request is finished

ImageReader.getImagesUrls(this, "https://myrstcco.000webhostapp.com/productionData.json", new ICallback<ArrayList<String>>() 
{
            @Override
            public void onSucess(ArrayList<String> urls) {
                 PagerAdapter adapter = new ProductionViewPagerAdapter(this, urls);
                 //continue here...
            }
            @Override
            public void onError(String message, int code) {
                 throw new RuntimeException("Error not treated: "+message + " " + code);
            }
}
);

1 - Also, open this link to know how to create singleton for your request queue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM