等待 Google 在 AsyncTask 中放置照片请求

Posted

技术标签:

【中文标题】等待 Google 在 AsyncTask 中放置照片请求【英文标题】:Wait for Google places Photo request inside 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 中 【参考方案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);
        
    ;

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

谢谢!

【讨论】:

以上是关于等待 Google 在 AsyncTask 中放置照片请求的主要内容,如果未能解决你的问题,请参考以下文章

Google Cloud Run (GCR) 的 Gunicorn (with Flask) 参数 - 在 Dockerfile 中放置啥? [关闭]

在 Android Studio 中放置 credentials.json 的位置

Android 无法在 main-dex 文件中放置请求的类

有没有办法用 Shiny R 在 textInput 中放置超链接

在 RecyclerView 网格中放置一个不确定的进度条作为页脚

在主线程中等待 AsyncTask