Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.4k views
in Technique[技术] by (71.8m points)

java - Volley concurrency problem with loop of get request

I have implemented an Android plugin for Unity which peform a call to webapi service

ClientPlugin class functionality

1)the api called is unauthorizedDateRequest, it make a request with the date of last update as parameter, the response is a JsonArray that contains object with 2 attributes: ID and Name

2)for each ID i make a second call to unauthorizedImageRequest, which is an ImageRequest of Volley, i've made class MyImageRequest that extends ImageRequest, in order to get the name from header fields

3)I pass response(bitmap) and nameFile to saveImageToGallery, this function symply save the downloaded bitmap

Problems comes randomly cause sometimes all images (for this demo i have 4 images) are saved, and other times only 3 of 4 image are saved and one of the 3 image is saved 2 times in a row, I assume it's a problem of concurrency, although Volley is thread safe

How can i solve this problem?

This is my code of class ClientPlugin

public class ClientPlugin {

private static final ClientPlugin newInstance = new ClientPlugin();
private String url;
private  NetworkManager networkManager;
public static Activity mainActivity;

public String imageName;

private static ClientPlugin getInstance() {return newInstance;}

public ClientPlugin() {
    String LOGCAT = "--ClientPlugin---";
    Log.i(LOGCAT,"Created DownloadPlugin");
}

public void unauthorizedDateRequest(){
    String LOGCAT ="-------------unauthorizedDateRequest-------------";

    String lastUpdate = getLastUpdateDate();
    url = "https://demo.companyName.com/api/ImagesList_na/date/"+lastUpdate;
    networkManager = NetworkManager.getInstance(mainActivity);
    RequestQueue queue = networkManager.getRequestQueue();
    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
            (Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
                @Override
                public void onResponse(JSONArray response) {
                    try {
                        for (int i = 0; i < response.length(); i++) {                              
                            JSONObject obj = response.getJSONObject(i);
                            String name =  obj.getString("ID");
                            unauthorizedImageRequest(name);
                        }
                    } catch (JSONException e) {
                        Log.e(LOGCAT, Log.getStackTraceString(e));
                    }
                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    String LOGCAT = "---DateRequestonErrorRespone---";
                    Log.e(LOGCAT, Log.getStackTraceString(error));

                }
            });
    queue.add(jsonArrayRequest);

}

public void unauthorizedImageRequest(String id){

    networkManager = NetworkManager.getInstance(mainActivity);
    RequestQueue queue = networkManager.getRequestQueue();

    url = "https://demo.companyName.com/api/Image_na/" + id;
    MyImageRequest request = new MyImageRequest(
            url, // Image URL
            new Response.Listener<Bitmap>() { // Bitmap listener
                @Override
                public void onResponse(Bitmap responseBitmap) {
                    String LOGCAT ="----onResponse----";
                    String nameFile = MyImageRequest.getMyNameFile();
                    // Save this downloaded bitmap to internal storage                    
                    Uri uri = saveImageToGallery(responseBitmap, nameFile)
                    Log.d(LOGCAT, uri.toString());
                }
            },
            0, 
            0, 
            null,
            Bitmap.Config.RGB_565, //Image decode configuration
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    String LOGCAT ="---ErroreOnRespone---";
                    Log.e(LOGCAT, Log.getStackTraceString(error));
                }
            }
    );

    request.setRetryPolicy(new DefaultRetryPolicy(
            5000,
            5,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    queue.add(request);

}

public Uri saveImageToGallery(Bitmap responseBitmap, String nameFile){
    String LOGCAT = "------saveImageToGallery-------";
    ContextWrapper wrapper = new ContextWrapper(mainActivity.getApplicationContext());

    File pathFile = wrapper.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File file = new File(pathFile,nameFile);
    try{
        OutputStream stream = null;
        stream = new FileOutputStream(file);

        responseBitmap.compress(Bitmap.CompressFormat.JPEG,100,stream);

        stream.flush();
        stream.close();
        Log.d(LOGCAT, "Image Saved");
    } catch (FileNotFoundException e) {
        Log.d(LOGCAT, Log.getStackTraceString(e));
    } catch (IOException e) {
        Log.d(LOGCAT, Log.getStackTraceString(e));
    }
    // Parse the gallery image url to uri
    Uri savedImageURI = Uri.parse(file.getAbsolutePath());

    // Return the saved image Uri
    return savedImageURI;
}

}

Code of NetworkManager class, this is a singleton

public class NetworkManager {
private static NetworkManager instance;
private RequestQueue requestQueue;

public synchronized static  NetworkManager getInstance(Activity activity) {
    if (instance == null) {
        instance = new NetworkManager();
        instance.requestQueue = Volley.newRequestQueue(activity);
    }
    return instance;
}

public RequestQueue getRequestQueue() {
    return requestQueue;
}
}

And this is code of MyImageRequest, i've implemented this class because i needed to Override parseNetworkResponse in order to retrieve name file from headers fields

    public class MyImageRequest extends ImageRequest {
private final String LOGCAT ="-----------parseNetworkResponse-----------";

private static String myNameFile="";

public static String getMyNameFile() {
    return myNameFile;
}

public MyImageRequest(String url, Response.Listener<Bitmap> listener, int maxWidth, int maxHeight, ImageView.ScaleType scaleType, Bitmap.Config decodeConfig, @Nullable Response.ErrorListener errorListener) {
    super(url, listener, maxWidth, maxHeight, scaleType, decodeConfig, errorListener);
}

@Override
protected Response<Bitmap> parseNetworkResponse(NetworkResponse response) {
    String tmpContentDisposition = response.headers.get("Content-Disposition");
    tmpContentDisposition = tmpContentDisposition.substring(21);
    Log.d(LOGCAT,tmpContentDisposition);
    myNameFile = tmpContentDisposition;
    return super.parseNetworkResponse(response);
}
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...