【问题标题】:ANR effect when using Volley使用 Volley 时的 ANR 效果
【发布时间】:2021-03-17 21:08:58
【问题描述】:

我已经尝试解决这个问题两天了。不幸的是,改进很少。

我使用的是BottomNavigationView,它使用getSupportFragmentManager().beginTransaction().replace(...切换片段

每个片段在创建时都会使用 Volley 调用 API。示例:

public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_services, container, false);

        ....

        callAPI();
}
private void callAPI() {
        VolleyUtils.makeJsonObjectRequest(context, ..., new VolleyResponseListener() {

            @Override
            public void onError(String message) {
                  System.out.println("Error: " + message);
            }
            
            @Override
            public void onResponse(String response) {
                  //JSON processing
                  //textView.setText(...);
            }
        }
}

VolleyUtils.java:

public class VolleyUtils {

    public static void makeJsonObjectRequest(Context context, ..., final VolleyResponseListener listener) {
        StringRequest jsonObjectRequest = new StringRequest
                (Request.Method.POST, "API URL", listener::onResponse, error -> listener.onError(error.toString())) {

            @Override
            public byte[] getBody() {
                //DATA
            }

            @Override
            protected Response<String> parseNetworkResponse(NetworkResponse response) {
                try {
                    String jsonString = new String(response.data,
                            HttpHeaderParser.parseCharset(response.headers));
                    JSONObject responseObj = new JSONObject(jsonString);
                    jsonString = responseObj.getJSONObject("response").toString();
                    //System.out.println(jsonString); //TODO remove debug line
                    return Response.success(jsonString,
                            HttpHeaderParser.parseCacheHeaders(response));
                } catch (UnsupportedEncodingException | JSONException e) {
                    return Response.error(new ParseError(e));
                }
            }
        };

        // Access the RequestQueue through singleton class.
        VolleySingleton.getInstance(context).addToRequestQueue(jsonObjectRequest);
    }
}

VolleySingleton.java:

public class VolleySingleton {
    @SuppressLint("StaticFieldLeak")
    private static VolleySingleton instance;
    private RequestQueue requestQueue;
    @SuppressLint("StaticFieldLeak")
    private static Context ctx;

    private VolleySingleton(Context context) {
        ctx = context;
        requestQueue = getRequestQueue();
    }

    public static synchronized VolleySingleton getInstance(Context context) {
        if (instance == null)
            instance = new VolleySingleton(context);
        return instance;
    }

    public RequestQueue getRequestQueue() {
        if (requestQueue == null)
            requestQueue = Volley.newRequestQueue(ctx.getApplicationContext());
        return requestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }
}

VolleyResponseListener:

public interface VolleyResponseListener {
    void onError(String message);

    void onResponse(String response);
}

问题是使用BottomNavigationView切换片段时出现ANR效果

我通过以下方式实现的最佳改进:

APIRunnable apiRunnable = new APIRunnable();
thread = new Thread(apiRunnable);
thread.start();

...

class APIRunnable implements Runnable {
        @Override
        public void run() {
            callAPI();
        }
    }

但是随着更快的切换,ANR 效应仍然会发生

I/Choreographer: Skipped 64 frames! The application may be doing too much work on its main thread.

我真的不知道如何解决它了。我很乐意为您提供任何帮助

谢谢

【问题讨论】:

  • 我强烈建议从 Volley 迁移到 Retrofit。您将为自己省去很多目前遇到的麻烦
  • @IvanWooll 好的,让我试试
  • @IvanWooll 更糟:(
  • @IvanWooll 现在模拟器中也会出现ANR,之前没有发生过

标签: android android-fragments android-volley bottomnavigationview android-anr-dialog


【解决方案1】:

我解决了问题:

我没有意识到,当我请求 API 时,我调用了一个生成 POST 数据的方法。

我现在用new Thread 调用这个方法,然后调用API。

这样就解决了问题,即使快速切换,一切都很顺利。

不过,我也从 Volley 切换到 Retrofit。

感谢伊万的帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    • 2018-07-27
    • 2012-02-13
    • 2016-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多