Подождите, пока Google разместит запрос фотографии внутри AsyncTask - PullRequest
0 голосов
/ 10 января 2020

Я пытаюсь понять, как использовать Asynctasks с другими запросами в них, поэтому я получаю фотографию с помощью Google мест, находясь внутри AsyncTask.

Что я получаю, так это то, что во время обработки запроса Asynctask завершается до того, как я получаю фотографию, поэтому она становится нулевой.

Я считаю, что проблема заключается в том, что во время выполнения запроса задание завершается и переходит к остальной части кода.

Мой класс AsyncTask построен так:

private class AsyncPhotoBuilder extends AsyncTask<Integer, Integer, Bitmap[][]>{

    ProgressBar pb;
    int status = 0;

    private void setProgressBar(ProgressBar progressBar){
        this.pb = progressBar;
    }

    @Override
    protected void onPostExecute(Bitmap[][] bitmaps) {
        super.onPostExecute(bitmaps);
        Log.d("debug", "onpost");
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        pb.setProgress(values[0]);
    }

    @Override
    protected Bitmap[][] doInBackground(Integer... integers) {
        try{
            int xSize = 4, ySize = 4;
            SharedPreferences prefs = getSharedPreferences(PHOTO_PREF, MODE_PRIVATE);
            String meta = prefs.getString("meta", "empty");
            if(!meta.equals("empty")){
                int loc = meta.indexOf(photoref_loc);
                String holder = meta.substring(loc+photoref_loc.length());
                PhotoMetadata temp = PhotoMetadata.builder(holder.substring(0, holder.length()-1)).build();


                FetchPhotoRequest photoRequest = FetchPhotoRequest.builder(temp)
                        .setMaxWidth(800) // Optional.
                        .setMaxHeight(800) // Optional.
                        .build();
                //Starts a request for a photo
                placesClient.fetchPhoto(photoRequest).addOnSuccessListener((fetchPhotoResponse) -> {
                    Photo_Bitmap.set(fetchPhotoResponse.getBitmap());
                    int width, height;

                    width = Photo_Bitmap.get().getWidth()/xSize;
                    height = Photo_Bitmap.get().getHeight()/ySize;
                    //Cuts photo into a 4x4
                    for(int i = 0; i < xSize; i++){
                        for(int j = 0; j < ySize; j++){
                            PuzzleList[i][j] = Bitmap.createBitmap(Photo_Bitmap.get(), i*width, j*height, width, height);
                            status++;
                            publishProgress(status);

                        }
                    }
                    //Once finished cutting photo raise flag.
                    ready_flag = true;
                    Log.d("debug", "finish");
                }).addOnFailureListener((exception) -> {
                    if (exception instanceof ApiException) {
                        ApiException apiException = (ApiException) exception;
                        int statusCode = apiException.getStatusCode();
                        // Handle error with given status code.
                        Log.e("debug", "Photo not found: " + exception.getMessage());
                    }
                });
            }
        }
        catch (Exception e){
            Log.d("Exception", "Error in splitting photo: " + e);
        }
        return PuzzleList;
    }
}

Насколько я понимаю, onPostExecute происходит до того, как запрос будет выполнен. Я попробовал несколько подходов к этому:

1 Используя функцию get () Asynctasks

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    /*
    Code...
    */

    asyncPhotoBuilder = new AsyncPhotoBuilder();
    asyncPhotoBuilder.setProgressBar(progressBar);
    asyncPhotoBuilder.execute(5000);
    try{
        PuzzleList = asyncPhotoBuilder.get(5000, TimeUnit.MILLISECONDS);
    }
    catch (ExecutionException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (TimeoutException e) {
        e.printStackTrace();
    }

    /*
    Code...
    */
}

Но я думаю, что она сталкивается с той же проблемой, что и задача, завершенная перед запросом.


1 Ответ

0 голосов
/ 10 января 2020

Когда я писал это, я решил свою проблему.

Я установил флаг внутри запроса (ready_flag), который был поднят после завершения запроса.

Использование запускаемого объекта чтобы проверить на момент, как задача была завершена, так и флаг был поднят.

Не уверен, что это лучший способ, которым я мог бы справиться с этим.

    public Runnable Start = new Runnable() {
        @Override
        public void run() {
            if(asyncPhotoBuilder.getStatus() == AsyncTask.Status.FINISHED && ready_flag){
                Init_start();
            }
            hand.postDelayed(this, 0);
        }
    };

Если есть лучшее способ сделать это, я люблю учиться.

Спасибо!

...