长时间运行后凌空撞击应用程序服务

我实现了一项服务来从服务器获取更新,如下所示:

public class Myupdates extends Service { private static final String TAG = "AutoUpdates"; private static final int started = 0; static SQLiteDatabase db; private boolean isRunning = false; private CountDownTimer timer; @Override public void onCreate() { this.db = openOrCreateDatabase("db", Context.MODE_PRIVATE, null); //Log.i(TAG, "Service onCreate"); isRunning = true; } int mCount = 1; @Override public int onStartCommand(Intent intent, int flags, int startId) { //Log.i(TAG, "Service onStartCommand"); //Creating new thread for my service //Always write your long running tasks in a separate thread, to avoid ANR new Thread(new Runnable() { @Override public void run() { if (isRunning) { new Timer().scheduleAtFixedRate(new TimerTask() { @Override public void run() { updates(); } }, 0, 30000); } //Stop service once it finishes its task //stopSelf(); } }).start(); return Service.START_STICKY; } @Override public IBinder onBind(Intent arg0) { //Log.i(TAG, "Service onBind"); return null; } @Override public void onDestroy() { isRunning = false; //Log.i(TAG, "Service onDestroy"); } /* HANDLE ADVERTS */ protected void updates() { /* JSON */ final JSONObject json = new JSONObject(); final JSONObject manJson = new JSONObject(); try { manJson.put("userid", "4444"); manJson.put("version", "6.0"); final String j = json.put("UPDATE", manJson).toString(); final String base_url = "https://myweburl.com"; // Instantiate the RequestQueue. RequestQueue queue = Volley.newRequestQueue(this); // Request a string response from the provided URL. StringRequest stringRequest = new StringRequest(Request.Method.POST, base_url, new Response.Listener() { @Override public void onResponse(String response) { //Log.i(TAG, "received "+response); try { JSONObject object = (JSONObject) new JSONTokener(response).nextValue(); String update = object.getString("UPDATE"); } catch (JSONException e) { return; } return; } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { //perform operation here after getting error return; } }) { @Override protected Map getParams() { Map params = new HashMap(); //pack message into json try { params.put("data", j.toString()); } catch (Exception e) { //Log.i(TAG,"Map error: Unable to compile post"); } return params; } @Override public Map getHeaders() throws AuthFailureError { Map params = new HashMap(); params.put("Content-Type", "application/x-www-form-urlencoded"); return params; } }; // Add the request to the RequestQueue. queue.add(stringRequest); // ends here return; } catch (Exception e) { //Log.i(TAG,"ERROR: Unable to get setup settings"); } // end exception write return; } } 

但是,在长时间运行服务后,应用程序崩溃并出现以下错误:

03-08 00:19:41.570 11239-11253 / com.mobiledatabook.com.dialcode E / AndroidRuntime:FATAL EXCEPTION:Timer-0进程:com.mobiledatabook.com.dialcode,PID:11239 java.lang.OutOfMemoryError:pthread_create(堆栈大小16384字节)失败:在com.android.volley.RequestQueue.start(RequestQueue.java)的java.lang.Thread.start(Thread.java:1029)上再次尝试java.lang.VMThread.create(Native Method) :152)com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:66)at com.andobile.volley.toolbox.Volley.newRequestQueue(Volley.java:78)at com.mobiledatabook.com.dialcode。 Myupdates.iDialAutoUpdates(Myupdates.java:128)at com.mobiledatabook.com.dialcode.Myupdates $ 1 $ 1.run(Myupdates.java:74)at java.util.Timer $ TimerImpl.run(Timer.java:284)

错误:java.lang.OutOfMemoryError。

有人可以帮我改进这段代码,以免在长时间运行服务后崩溃应用程序吗?

之所以发生这种情况,是因为您通过传递活动context多次创建RequestQueue实例。 您应该使用Application类创建一次实例,然后在需要时再次使用它。 创建这样的应用程序类,

 public class AppController extends Application { private static AppController sInstance; private RequestQueue mRequestQueue; @Override public void onCreate() { super.onCreate(); sInstance = this; } public static synchronized AppController getInstance() { return sInstance; } public RequestQueue getRequestQueue() { if (mRequestQueue == null) { mRequestQueue = Volley.newRequestQueue(getApplicationContext()); } return mRequestQueue; } } 

然后像这样使用它

 RequestQueue queue=AppController.getInstance().getRequestQueue(); 

注意 :通过一次又一次地将上下文传递给请求队列,您正在填充ram,当没有更多空间可以分配时,这会导致OutOfMemoryException

正如android官方文档中所述,

一个关键概念是RequestQueue必须使用Application上下文实例化,而不是Activity上下文。 这可确保RequestQueue将持续应用程序的生命周期,而不是每次重新创建活动时重新创建(例如,当用户旋转设备时)。