【问题标题】:Problems in understating execution flow in android studio在 android studio 中低估执行流程的问题
【发布时间】:2018-12-12 09:13:36
【问题描述】:

以下代码使用改造和 youtubedata api 来获取两个 youtube 频道的订阅者数量。

public class NavigationActivity extends AppCompatActivity {


private static String GOOGLE_YOUTUBE_API_KEY = "AIzaSyBV4XQEZ9l1HZeBQFL6ZZvHYfMhtnqUkmw";
private static String CHANNEL_ID_TS = "UCq-Fj5jknLsUf-MWSy4_brA";
private static String CHANNEL_ID_PDP = "UC-lHJZR3Gqxm24_Vd_AJ5Yw";
public static int SUBS_TS = 0;
public static int SUBS_PDP = 0;

//?part=snippet%2CcontentDetails%2Cstatistics&id=UC_x5XG1OV2P6uZZ5FSM9Ttw&key=AIzaSyBV4XQEZ9l1HZeBQFL6ZZvHYfMhtnqUkmw

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_navigation);

    Map<String, String> qMap = new HashMap<>();
    qMap.put("part", "snippet,contentDetails,statistics");
    qMap.put("id", CHANNEL_ID_TS);
    qMap.put("key", GOOGLE_YOUTUBE_API_KEY);


    Map<String, String> qMap2 = new HashMap<>();
    qMap2.put("part", "snippet,contentDetails,statistics");
    qMap2.put("id", CHANNEL_ID_PDP);
    qMap2.put("key", GOOGLE_YOUTUBE_API_KEY);

    ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);

    Call<ChannelResponse> call = apiService.getSubs(qMap);

        call.enqueue(new Callback<ChannelResponse>() {
            @Override
            public void onResponse(Call<ChannelResponse> call, Response<ChannelResponse> response) {

                List<Channel> channels = response.body().getChannels();
                SUBS_TS = channels.get(0).getStatistics().getSubscriberCount();
                Log.d("GEEK", SUBS_TS + "");

            }

            @Override
            public void onFailure(Call<ChannelResponse> call, Throwable t) {
                Log.d("GEEK", t.toString());
            }
        });


        Call<ChannelResponse> call2 = apiService.getSubs(qMap2);
        call2.enqueue(new Callback<ChannelResponse>() {
            @Override
            public void onResponse(Call<ChannelResponse> call, Response<ChannelResponse> response) {

                List<Channel> channels = response.body().getChannels();
                SUBS_PDP = channels.get(0).getStatistics().getSubscriberCount();
                Log.d("GEEK", SUBS_PDP + "");

            }

            @Override
            public void onFailure(Call<ChannelResponse> call, Throwable t) {
                Log.d("GEEK", t.toString());
            }
        });

        //This statement seems to be executed before the SUSB_TS and SUSB_PDP variables are updated using the response. 
        Log.d("GEEK", SUBS_PDP + "AFTER");

}

}

为什么是

Log.d("GEEK", SUBS_PDP + "AFTER");

在 onResponse 方法之前执行的语句?

日志

2018-12-12 14:30:26.993 17518-17518/com.geek.wartube D/GEEK: 0AFTER
2018-12-12 14:30:27.863 17518-17518/com.geek.wartube D/GEEK: 76222082
2018-12-12 14:30:27.885 17518-17518/com.geek.wartube D/GEEK: 75161493

我还使用调试器检查了 onResponse 中的语句在最后一行的日志语句之前没有执行。


我应该怎么做才能达到预期的效果?

【问题讨论】:

  • 我认为您不能提及您的 youtube API 密钥.....删除它,因为它不安全
  • @Deepanshutyagi 我很快就会禁用它
  • 你入队的方法放在不同的线程上。代码触发这些线程,当前线程跳转到它必须遵循的下一个可用代码行,在本例中为日志。在打印日志时,其他线程上的方法将被执行,因此您的日志将打印在“之后”日志下方。

标签: android android-studio retrofit2 oncreate


【解决方案1】:

对 apiService.getSubs(qMap) 和 apiService.getSubs(qMap2) 方法的调用在后台线程中完成。这就是为什么在响应完成之前执行下一条语句的原因。因此语句 Log.d("GEEK", SUBS_PDP + "AFTER");在 onResponse() 方法之前执行

您可以在第一次调用的 onResponse() 中执行第二次调用,在第二次调用的 onResponse() 中执行您接下来想做的任何事情,或者如果可能的话使用 Rxjava。但是第一种方法很容易理解

【讨论】:

  • 您建议的方法将不起作用,因为该语句在它们之前执行
  • 创建一个函数并检查它, SUBS_TS , SUBS_PDP 不等于零然后做你想做的,在底部的两个响应中调用该函数。
  • 这就是为什么我告诉你把语句放在第二次调用的 onResponse() 中
猜你喜欢
  • 2021-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-19
  • 2017-06-07
  • 1970-01-01
  • 2017-08-18
相关资源
最近更新 更多