首页 > 解决方案 > 我正面临 Volley Time out Error 和 mainThread 错误

问题描述

我正在尝试使用 Volley 库在 Andriod 应用程序中获取数据以形成服务器。当我请求获取数据时我的数据太大,但问题是凌空超时错误,我也使用了 RetryPolicy,但问题是一样的。我该如何解决?

我已经尝试过 RetryPolicy 和 AsynTask 但我的问题无法解决。谁能告诉我如何解决这个问题?//这里的主要功能...

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search_member);

        initiateViews();
        searchViewCategory();


    }

//initiateViews function...
    private void initiateViews() {
        recyclerView = findViewById(R.id.search_category_recyle_view);
        mSearchView = findViewById(R.id.searchView);
        addMember = findViewById(R.id.addMember);
        requestQueue = Volley.newRequestQueue(this);
    }

    private void searchViewCategory() {
        mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {

                getData();
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                return false;
            }
        });
    }
//Get Data from Server function
public void getData()
{
    JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, "http://alfahd.witorbit.net/api.php?search_member=a&array=1", new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObjectresponse)
        {
            Toast.makeText(SearchMember.this, "" + response, Toast.LENGTH_SHORT).show();
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error)
        {
            error.printStackTrace();
            dialog.dismiss();
            Toast.makeText(SearchMember.this, "Error", Toast.LENGTH_SHORT).show();
        }
    });
    request.setRetryPolicy(new DefaultRetryPolicy(
            MY_SOCKET_TIMEOUT_MS,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    requestQueue.add(request);

}


The application may be doing too much work on its main thread.
VolleyTimeOutError()

标签: javaandroidandroid-asynctaskandroid-volley

解决方案


因此,起初强烈建议使用 Volley Singleton 模式来充分利用它。我的凌空单例课是这样的。

/**
 * Created by MuhammadFaisal on 8/10/2017.
 */

public class VolleySingleton {
private static final int MAX = 2 * 1024 * 1024;
private static int MAX_SERIAL_THREAD_POOL_SIZE = 10;
private static VolleySingleton mSingletonInstance = null;
private final int MAX_CACHE_SIZE = 2 * 1024 * 1024; //2 MB
Context context = null;
private ImageLoader imageLoader;
private RequestQueue volleyRequestQueue;

private VolleySingleton(Context c)
{

    RequestQueue serialRequestQueue = prepareSerialRequestQueue(c);
    serialRequestQueue.start();
    context = c;

    volleyRequestQueue = Volley.newRequestQueue(c);
    imageLoader = new ImageLoader(volleyRequestQueue, new ImageLoader.ImageCache() {
        private LruCache<String, Bitmap> mCache = new LruCache<>((int) (Runtime.getRuntime().maxMemory() / 1024 / 8));

        @Override
        public Bitmap getBitmap(String url)
        {
            return mCache.get(url);
        }

        @Override
        public void putBitmap(String url, Bitmap bitmap)
        {
            mCache.put(url, bitmap);
        }
    });
}

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

public static RequestQueue prepareSerialRequestQueue(Context context)
{
    Cache cache = new DiskBasedCache(context.getCacheDir(), MAX);
    Network network = getNetwork();
    RequestQueue requestQueue;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
            && Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT)
    {
        try
        {
            if (checkGooglePlayServices(context))
                ProviderInstaller.installIfNeeded(context);
        }
        catch (GooglePlayServicesRepairableException e)
        {
            // Indicates that Google Play services is out of date, disabled, etc.
            // Prompt the user to install/update/enable Google Play services.
            GooglePlayServicesUtil.showErrorNotification(e.getConnectionStatusCode(), context);
            // Notify the SyncManager that a soft error occurred.
            //syncResult.stats.numIOExceptions++;
            return null;
        }
        catch (GooglePlayServicesNotAvailableException e)
        {
            // Indicates a non-recoverable error; the ProviderInstaller is not able
            // to install an up-to-date Provider.
            // Notify the SyncManager that a hard error occurred.
            //GooglePlayServicesUtil.showErrorNotification(e.getConnectionStatusCode(), context);
            //syncResult.stats.numAuthExceptions++;
            return null;
        }

        HttpStack stack = null;
        try
        {
            stack = new HurlStack(null, new TLSSocketFactory());
        }
        catch (KeyManagementException e)
        {
            e.printStackTrace();
            Log.d("Your Wrapper Class", "Could not create new stack for TLS v1.2");
            stack = new HurlStack();
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
            Log.d("Your Wrapper Class", "Could not create new stack for TLS v1.2");
            stack = new HurlStack();
        }
        requestQueue = Volley.newRequestQueue(context, stack);
        return requestQueue;
    }
    else
        return new RequestQueue(cache, network, MAX_SERIAL_THREAD_POOL_SIZE);
}

private static Network getNetwork()
{
    HttpStack stack;
    String userAgent = "volley/0";
    if (Build.VERSION.SDK_INT >= 9)
    {
        stack = new HurlStack();
    }
    else
    {
        stack = null;
        //stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
    }
    return new BasicNetwork(stack);
}

private static boolean checkGooglePlayServices(Context con)
{
    switch (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(con))
    {
        case ConnectionResult.SERVICE_MISSING:
            Log.d("googleError: ", Integer.toString(ConnectionResult.SERVICE_MISSING));
            //GoogleApiAvailability.getInstance().getErrorDialog(SplashScreen.this,ConnectionResult.SERVICE_MISSING,0).show();
            break;
        case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
            Log.d("googleError: ", Integer.toString(ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED));
            //GoogleApiAvailability.getInstance().getErrorDialog(this,ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED,0).show();
            break;
        case ConnectionResult.SERVICE_DISABLED:
            Log.d("googleError: ", Integer.toString(ConnectionResult.SERVICE_DISABLED));
            //GoogleApiAvailability.getInstance().getErrorDialog(this,ConnectionResult.SERVICE_DISABLED,0).show();
            break;
    }
    return true;
}

public RequestQueue getVolleyRequestQueue()
{
    if (volleyRequestQueue == null)
    {
        // getApplicationContext() is key, it keeps you from leaking the
        // Activity or BroadcastReceiver if someone passes one in.
        volleyRequestQueue = Volley.newRequestQueue(context.getApplicationContext());
    }
    return volleyRequestQueue;
}

public ImageLoader getImageLoader()
{
    return imageLoader;
}
}

使用单例方法有很多好处,其中一个主要好处是它为您提供了一个请求队列来执行所有网络请求。现在,像这样初始化你的 requestQueue:

private RequestQueue requestQueue;
if (requestQueue == null)
        requestQueue = VolleySingleton.getInstance(context).getVolleyRequestQueue();

您现在可以开始进行这样的网络调用,只是为了让您知道我使用相同的方法来调用您的端点并成功获得响应。

JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, "http://alfahd.witorbit.net/api.php?search_member=a&array=1", new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response)
        {
            volleyCallBack.onSuccess(response.toString());
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error)
        {
            JSONObject jsonObject;
            NetworkResponse networkResponse = error.networkResponse;
            if (networkResponse != null && networkResponse.data != null)
            {
                String jsonError = new String(networkResponse.data);
                if(jsonError.contains("500"))
                    createErrorDialog("Something went wrong. Try Later!","");
            }
            volleyCallBack.onFailure(error);
        }
    }) 
//        {
//            @Override
//            public byte[] getBody()
//            {
//                return jsonObject.toString().getBytes();
//            }
//
//            @Override
//            public Map<String, String> getHeaders()
//            {
//                Map<String, String> params = new HashMap<String, String>();
//                params.put("Authorization", "Bearer " + jwt);
//                params.put("Content-Type", "application/json");
//                return params;
//            }
//        };
    jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
            0,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    requestQueue.add(jsonObjectRequest);

推荐阅读