【问题标题】:assign external variable to the result of a callback inside AsynckTask将外部变量分配给 AsynckTask 内的回调结果
【发布时间】:2016-10-10 04:03:15
【问题描述】:
private class exampleTask extends AsyncTask<String, Void, SomeResult>{
    @Override
    protected SomeResult doInBackground(String... urls) {
       SomeResult res ; 
       someMethod(new CallBack<T>(){
              @Override
              public void onResponse(SomeResult something) {
                res = something ; 
             }

            @Override
            public void onFailure() {
                //
            }
       });

     return res ;
    }


    @Override
    protected void onPostExecute() {
        //
    }
}

我想将“res”分配给“某物”,女巫在 onResponse 方法的回调中。在这段代码中,不可能在 onResponse 方法中分配 res 。

欢迎任何帮助。

谢谢你:)

我的原始代码:我想分配“url”;

private class GetBeaconInfosTask extends AsyncTask<String, Void, Call<Url>> {

    Url url ;

    @Override
    protected Call<Url> doInBackground(String... urls) {
        ProxService service = ProxService.Factory.makeProxService(ProxService.ENDPOINT);
        return service.getUrlDetails(urls[0]);
    }

    // onPostExecute return the results of the AsyncTask.
    @Override
    protected void onPostExecute(Call<Url> call) {

        call.enqueue(new Callback<Url>() {
            @Override
            public void onResponse(Call<Url> call, Response<Url> response) {
                url = response.body();
            }

            @Override
            public void onFailure(Call<Url> call, Throwable t) {
                //
            }
        });

        if(url == null){
            Log.i("url is null", "url is null !!!!!  ....");
        }
        else {
        setShopLogo(url.icon) ;
        setShopName(url.title);
        setDescription(url.description);
        setlongUrl(url.longUrl); }
    }

}

【问题讨论】:

  • 为什么不可能?因为它不是最终的?您可以通过使用 SomeResult 的最终数组并在数组的第一行中分配值来作弊。 Android Studio 应该会向您推荐这个解决方案。
  • 你直接返回 res onResponse 怎么样,你不需要存储它。

标签: java android android-asynctask callback asynccallback


【解决方案1】:

假设问题是由于必须将变量声明为 final 才能从回调中访问,您可以将其移出 doInBackground 方法并将其声明为 exampleTask 类的成员。

    private class exampleTask extends AsyncTask<String, Void, SomeResult>{
            SomeResult res;

            @Override
            protected SomeResult doInBackground(String... urls) {

               someMethod(new CallBack<T>(){
                  @Override
                  public void onResponse(SomeResult something) {
                    res = something ; 
                 }

                @Override
                public void onFailure() {
                    //
                }
           });

         return res ;
        }


        @Override
        protected void onPostExecute() {
            //
        }
    }

虽然这应该可以回答您的问题,但很难说出您想要实现的目标。除了@Gabe Sechan 的回答 - 你的变量可能永远不会被分配,或者它会在一段时间后被分配。通常,您将在 doInBackground 中执行工作,并在执行时调用 onPostExecute ,但在您的情况下,您可能会在点击回调的 onRespons 之前调用 onPostExecute 。我认为在 doInBackground 中以您尝试使用的方式使用回调不是一个好习惯。

如果您有其他需要在 doInBackground 中异步执行的工作,请执行此操作,但将 someMethod 调用移至 onPostExecute 并在其中使用 res 执行您需要执行的任何操作。

private class exampleTask extends AsyncTask<String, Void, SomeResult>{
    SomeResult res;

    @Override
    protected SomeResult doInBackground(String... urls) {

       // background work
    }


    @Override
    protected void onPostExecute() {
       someMethod(new CallBack<T>(){
              @Override
              public void onResponse(SomeResult something) {
                res = something ;
               // DO STUFF WITH RES HERE AFTER IT'S BEEN ASSIGNED OR YOU WON'T HAVE ACCESS TO IT
             }

            @Override
            public void onFailure() {
                //
            }
       });
    }

}

编辑:既然问题包含真实代码,我可以提供一个适合您的流程。请注意,在我粘贴在 onResponse 注释上方的代码中,您应该在此处拥有使用该变量的代码。例如使用您的代码查看下面的 onResponse。在您到达 onResponse 回调方法之前,该值不存在,因此您必须等到它到达那里。您下面的代码是在 before onResponse 执行的,因此该变量不可避免地为空。代码不是按顺序执行的。我建议研究回调以完全理解它们:)

private class GetBeaconInfosTask extends AsyncTask<String, Void, Call<Url>> {

    Url url ;

    @Override
    protected Call<Url> doInBackground(String... urls) {
        ProxService service = ProxService.Factory.makeProxService(ProxService.ENDPOINT);
        return service.getUrlDetails(urls[0]);
    }

    // onPostExecute return the results of the AsyncTask.
    @Override
    protected void onPostExecute(Call<Url> call) {

        call.enqueue(new Callback<Url>() {
            @Override
            public void onResponse(Call<Url> call, Response<Url> response) {
                url = response.body();


                setShopLogo(url.icon) ;
                setShopName(url.title);
                setDescription(url.description);
                setlongUrl(url.longUrl); }
            }

            @Override
            public void onFailure(Call<Url> call, Throwable t) {
                //
            }
        });
}

【讨论】:

  • @Gabe Sechan 感谢 Karen Forde 的帮助。我尝试了您的解决方案,但 res 仍然为空:/ 请检查我的真实代码,我将编辑我的问题。谢谢
  • @Aymane 如上所述,在 onResponse 之外 res 将为空,因为它在调用 onResponse 之前到达那段代码。我将使用您应该使用的流程编辑此答案
  • 非常感谢您的帮助,它有效!你说得对,我需要学习和理解回调,实际上我是一个初学者,我正在开发我的第一个 mob 应用程序:)
  • @AymaneBo 没问题 - 祝您的第一个应用好运! :)
【解决方案2】:

您似乎不明白回调的目的。将来某个时候会调用回调。现在不要。因此,设置回调的函数在执行结束时不会被保证调用。你想要的永远不会奏效。相反,您应该在 onPostExecute 中使用回调主体中的值执行您想要执行的任何操作。

【讨论】:

    猜你喜欢
    • 2018-03-13
    • 2021-08-21
    • 1970-01-01
    • 2013-11-12
    • 2022-01-06
    • 2020-05-15
    • 2021-02-04
    • 1970-01-01
    • 2022-11-27
    相关资源
    最近更新 更多