簡體   English   中英

Java、Android Studio 中出現意外的類似協程的行為

[英]Unexpected Coroutine-like behaviour in Java, Android Studio

我正在處理多個 Retrofit API 調用和響應數據處理,這比我預期的要花費更多的時間。 因此,我在每個主要代碼塊之后添加了以下類型的語句:

Log.e(TAG, "CHECK {1}");

令我驚訝的是,大多數 Log 語句都是立即打印的,其順序與程序流程不同。 在處理后者的返回 object 之前,調用了依賴於不同 function 的參數的 function 。

這里究竟發生了什么? 有沒有辦法調整這種行為?

編輯:這是代碼的要點。


public void onViewCreated(View view, Bundle savedInstanceState){

    super.onViewCreated(view, savedInstanceState);

    Log.e(TAG, "CHECK 1");

    List<String> list = function1();

    Log.e(TAG, "CHECK 6");

    function2(list);

    Log.e(TAG, "CHECK 10");

}

private List<String> function1(){

    Log.e(TAG, "CHECK 2");

    List<String> list = new ArrayList<>();
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(urls.API_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    APIClass feedAPI = retrofit.create(APIClass.class);
    Call<APIResponse> call = feedAPI.list(parameter1, parameter2, parameter3);

    Log.e(TAG, "CHECK 3");

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

                Log.e(TAG, "onResponse: Server Response: " + response.toString());
                Log.e(TAG, "onResponse: Get Data: " + response.body().getData());

                Log.e(TAG, "CHECK 4");

                for (Object entry: response.body().getData()) {
                    Gson gson = new Gson();
                    Map<Object, Object> map = gson.fromJson(gson.toJson(entry), Map.class);
                    for (Object key: map.keySet())
                    {
                        if (key.toString().equals("xyz"))
                            list.add(map.get(key).toString());
                    }
                }

            }catch (NullPointerException e){
                Log.e(TAG, "onResponse: NullPointerException: " +e.getMessage() );
            }
        }

        @Override
        public void onFailure(Call<APIResponse> call, Throwable t) {
            Log.e(TAG, "onFailure: Unable to retrieve JSON: " + t.getMessage() );
            Toast.makeText(getActivity(), "An Error Occurred", Toast.LENGTH_SHORT).show();
        }
    });

    Log.e(TAG, "CHECK 5");

    return list;
}

private void function2(List<String> userlist){

    Log.e(TAG, "CHECK 7");

    //api callback and processing similar to function1, including a "CHECK 8"

    Log.e(TAG, "CHECK 9");
}

Logcat Output。

CHECK 1
CHECK 2
CHECK 3
CHECK 5
CHECK 6
CHECK 7
CHECK 9
CHECK 10
onResponse: Server Response: Response{...}
onResponse: Get Data: [...]

解決這個問題的方法是創建一個與主 UI 線程並行運行的新線程(或服務); 然后在新創建的線程中使用同步 API 調用,如下所示。

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(urls.API_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build();
APIClass feedAPI = retrofit.create(APIClass.class);
Call<APIResponse> call = feedAPI.list(parameter1, parameter2, parameter3);

try {
    Response<APIResponse> response = call.execute();
    Log.e(TAG, "onResponse: Server Response: " + response.toString());
    Log.e(TAG, "onResponse: Get Data: " + response.body().getData());

    for (Object entry: response.body().getData()) {
        Gson gson = new Gson();
        Map<Object, Object> map = gson.fromJson(gson.toJson(entry), Map.class);
        for (Object key: map.keySet())
        {
            if (key.toString().equals("xyz"))
                list.add(map.get(key).toString());
            }
        }
    }
}
catch (IOException e) {
    Log.e(TAG, "IOException: "+e);
}

要了解更多關於 Android 中的 Thread、Service 等的信息,請參閱這個問題: How can I fix 'android.os.NetworkOnMainThreadException'?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM