【问题标题】:Wait for Google places Photo request inside AsyncTask等待 Google 在 AsyncTask 中放置照片请求
【发布时间】:2020-04-27 16:25:10
【问题描述】:

我正在尝试了解如何将 Asynctasks 与其中的其他请求一起使用,因此我在 AsyncTask 中使用 Google 地点获取照片。

我得到的是,在处理请求时,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 使用 Asynctasks 的 get() 函数

@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...
    */
}

但我认为在请求之前完成任务会遇到同样的问题。


【问题讨论】:

  • 第一件事...... AsynTask 现在已被弃用。还有更好的选择
  • 什么比 Asyntask 更好?
  • 有什么理由让这个“异步两次”? FetchPhotoRequest.fetchPhoto 已经是异步的,无需将其包装在 AsyncTask 中

标签: android google-maps android-asynctask google-places-api


【解决方案1】:

在我写这篇文章的时候,我确实解决了我的问题。

我在请求中设置了一个标志 (ready_flag),一旦请求完成就会引发该标志。

使用 runnable 来检查任务完成和标志被升起的时刻。

不确定这是否是我可以处理的最佳方式。

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

如果有更好的方法来做到这一点,我喜欢学习。

谢谢!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 2022-10-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多