使用凌空内存错误的递归函数

时间:2016-07-30 14:18:49

标签: java android recursion android-volley stack-overflow

我正在使用Volley库与我的数据库进行通信。我使用递归函数连续检查我的数据库,但经过一段时间似乎递归函数停止工作,我得到以下错误:

FATAL EXCEPTION: main
 Process: com.example.sakis.loginregister, PID: 22637
 java.lang.OutOfMemoryError: pthread_create (stack size 131072 bytes) failed: Try again
     at java.lang.VMThread.create(Native Method)
     at java.lang.Thread.start(Thread.java:1029)
     at com.android.volley.RequestQueue.start(RequestQueue.java:145)
     at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:66)
     at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:78)
     at com.example.sakis.loginregister.MultiPlayerActivity.func(MultiPlayerActivity.java:342)
     at com.example.sakis.loginregister.MultiPlayerActivity$2.onResponse(MultiPlayerActivity.java:160)
     at com.example.sakis.loginregister.MultiPlayerActivity$2.onResponse(MultiPlayerActivity.java:133)
     at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)
     at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
     at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
     at android.os.Handler.handleCallback(Handler.java:808)
     at android.os.Handler.dispatchMessage(Handler.java:103)
     at android.os.Looper.loop(Looper.java:193)
     at android.app.ActivityThread.main(ActivityThread.java:5292)
     at java.lang.reflect.Method.invokeNative(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:515)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
     at dalvik.system.NativeStart.main(Native Method)

我认为当我没有及时得到正确的响应时,这是一个stackoverflow错误。这是我首先在onCreate方法中调用的递归函数代码:

void func(){

    reject=0;
    Response.Listener<String> response1Listener = new Response.Listener<String>() {
        @Override
        public void onResponse(final String response) {


            try {


                JSONObject jsonResponse = new JSONObject(response);

                request = jsonResponse.getInt("request");
                requestorigin = jsonResponse.getString("requestorigin");
                category = jsonResponse.getInt("category");
                dif_level = jsonResponse.getInt("dif_level");
                number_of_questions = jsonResponse.getInt("number_of_questions");
                time_of_answer = jsonResponse.getInt("time_of_answer");

                if(request==0)  {





                    func();

                }

                if (request == 1) {



                    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MultiPlayerActivity.this,R.style.myBackgroundStyle);
                    alertDialogBuilder.setMessage("Έχεις νέο αίτημα από τον χρήστη " + requestorigin + "\n" + "Κατηγορία Ερωτήσεων: " + array_category[category]
                            + "\n" + "Επίπεδο Δυσκολίας: " + array_dif_level[dif_level] + "\n" + "Αριθμός Ερωτήσεων: " + number_of_questions + "\n "
                            + "Χρόνος Απάντησης: " + time_of_answer);

                    alertDialogBuilder.setPositiveButton("Ναι", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface arg0, int arg1) {


                            Response.Listener<String> response1Listener = new Response.Listener<String>() {
                                @Override
                                public void onResponse(final String response) {


                                    try {


                                        JSONObject jsonResponse = new JSONObject(response);


                                    } catch (JSONException e)

                                    {

                                        e.printStackTrace();
                                    }


                                }


                            };


                            SendResponseRequest sendResponseRequest = new SendResponseRequest(username, response1Listener);
                            RequestQueue queue1 = Volley.newRequestQueue(MultiPlayerActivity.this);
                            queue1.add(sendResponseRequest);



                            Response.Listener<String> responseListener=new Response.Listener<String>() {
                                @Override
                                public void onResponse(String response) {

                                    try {
                                        JSONObject jsonResponse = new JSONObject(response);
                                        boolean success1=jsonResponse.getBoolean("success1");
                                        if(success1)  {
                                            Intent intent2 = new Intent(MultiPlayerActivity.this, MultiPlayerGame2Activity.class);
                                            intent2.putExtra("username1",username);
                                            intent2.putExtra("username2",requestorigin);
                                            intent2.putExtra("category", category);
                                            intent2.putExtra("dif_level", dif_level);
                                            intent2.putExtra("number_of_questions", number_of_questions);
                                            intent2.putExtra("time_of_answer", time_of_answer);
                                            intent2.putExtra("level", level);
                                            intent2.putExtra("score", score);
                                            intent2.putExtra("music",music);
                                            intent2.putExtra("sound",sound);
                                            startActivity(intent2);
                                            // android.os.Process.killProcess(android.os.Process.myPid());
                                            finish();
                                        }

                                    } catch (JSONException e)

                                    {

                                        e.printStackTrace();
                                    }


                                }
                            };




                            Back0Request back0Request = new Back0Request(username,responseListener);
                            RequestQueue queue = Volley.newRequestQueue(MultiPlayerActivity.this);
                            queue.add(back0Request);








                        }
                    });

                    alertDialogBuilder.setNegativeButton("Όχι", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {




                                    Response.Listener<String> response1Listener = new Response.Listener<String>() {
                                        @Override
                                        public void onResponse(final String response) {


                                            try {


                                                JSONObject jsonResponse = new JSONObject(response);
                                                reject = jsonResponse.getInt("reject");
                                                if(reject==1)  {
                                                    func();
                                                }

                                            } catch (JSONException e)

                                            {

                                                e.printStackTrace();
                                            }


                                        }


                                    };


                                    RejectRequestRequest rejectRequestRequest = new RejectRequestRequest(username, response1Listener);
                                    RequestQueue queue1 = Volley.newRequestQueue(MultiPlayerActivity.this);
                                    queue1.add(rejectRequestRequest);





                                        }

                    });


                    AlertDialog alertDialog = alertDialogBuilder.create();
                    alertDialog.show();




                }





            } catch (JSONException e)

            {

                e.printStackTrace();
            }


        }


    };


    //text2.setText("OK");
    CheckRequest checkRequest = new CheckRequest(username, response1Listener);
    /***
     int socketTimeout = 30000;//30 seconds - change to what you want
     RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
     checkRequest.setRetryPolicy(policy);
     ******/
    RequestQueue queue1 = Volley.newRequestQueue(MultiPlayerActivity.this);
    queue1.add(checkRequest);

    //text3.setText("After ");

}

当我从数据库获取的变量请求值为零时,我想再次检查数据库,直到它将采用非零值。有没有更好的方法来实现这一点,所以我可以避免递归,因为它会导致一些溢出错误。

1 个答案:

答案 0 :(得分:0)

当我使用Singleton Pattern并重新使用队列的同一实例时,问题解决了,这样可以防止出现内存不足错误:

public class MySingleton {
private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private static Context mContext;

private MySingleton(Context context){
    // Specify the application context
    mContext = context;
    // Get the request queue
    mRequestQueue = getRequestQueue();
}

public static synchronized MySingleton getInstance(Context context){
    // If Instance is null then initialize new Instance
    if(mInstance == null){
        mInstance = new MySingleton(context);
    }
    // Return MySingleton new Instance
    return mInstance;
}

public RequestQueue getRequestQueue(){
    // If RequestQueue is null the initialize new RequestQueue
    if(mRequestQueue == null){
        mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
    }

    // Return RequestQueue
    return mRequestQueue;
}

public<T> void addToRequestQueue(Request<T> request){
    // Add the specified request to the request queue
    getRequestQueue().add(request);
}