2014-07-11 21 views
0

我爲我的應用程序創建了一個後臺服務,但它顯示錯誤「在其主線程服務上做了太多工作」。而且它延伸到無法使用的地方。那麼,我的代碼有什麼問題?如何解決我的後臺服務中「在其主線程服務中做了太多工作」的錯誤?

public class TestService extends Service { 

    boolean serviceRun = true; 
    SharedPreferences prefs; 
    Editor editor; 
    int serverId; 
    int gameId; 
    JSONObject jsonObj; 
    NotificationManager m_notificationManager; 
    int NOTIFICATION_ID = 0; 

    @Override 
    public IBinder onBind(Intent intent) { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    public class MyBinder extends Binder { 
     public TestService getService() { 
      return TestService.this; 
     } 
    } 

    private ServiceConnection m_serviceConnection = new ServiceConnection() { 
     public void onServiceConnected(ComponentName className, IBinder service) { 
      Service m_service = ((TestService.MyBinder) service).getService(); 
     } 

     public void onServiceDisconnected(ComponentName className) { 
      Service m_service = null; 
     } 
    }; 

    @Override 
    public void onCreate() { 
     // TODO Auto-generated method stub 
     super.onCreate(); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

     prefs = getSharedPreferences(Constants.PREFS_NAME, Context.MODE_PRIVATE); 
     editor = prefs.edit(); 
     serverId = prefs.getInt(Constants.PREF_SERVER_ID, 0); 

     Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show(); 

     final Handler handler = new Handler() { 

      @Override 
      public void handleMessage(Message msg) { 
       super.handleMessage(msg); 
       if (isNetworkConnected()) { 
        for (int i = 0; i < prefs.getInt(Constants.PREF_FRIEND_COUNT, 0); i++) { 
         if (prefs.getBoolean(Constants.PREF_FRIEND_NOTIFICATION + i, true)) { 

          try { 
           jsonObj = new GetGames().execute(
             "apiurl.blabla").get(); 
           gameId = jsonObj.getJSONArray(Constants.JSON_GAMES).getJSONObject(0) 
             .getInt(Constants.JSON_GAME_ID); 

           if (gameId == prefs.getInt(Constants.PREF_LAST_GAME_ID + i, 0)) { 

           } else { 

            if (!prefs.getBoolean(Constants.PREF_FRIEND_FIRST_TIME + i, false)) { 

             addNotification(
               "Notification", i); 
             NOTIFICATION_ID++; 
            } else { 
             editor.putBoolean(Constants.PREF_FRIEND_FIRST_TIME + i, false); 
            } 

            editor.putInt(Constants.PREF_LAST_GAME_ID + i, gameId); 
            editor.commit(); 

           } 

          } catch (InterruptedException e) { 
           e.printStackTrace(); 
          } catch (ExecutionException e) { 
           e.printStackTrace(); 
          } catch (JSONException e) { 
           e.printStackTrace(); 
          } 
         } 

        } 
       } else { 

       } 
      } 

     }; 

     new Thread(new Runnable() { 
      public void run() { 
       while (true) { 
        try { 
         Thread.sleep(Constants.SERVICE_LOOP_INTERVAL * 1000); 
         handler.sendEmptyMessage(0); 

        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 

       } 

      } 
     }).start(); 

     return START_STICKY; 
    } 

    @Override 
    public void onDestroy() { 
     Toast.makeText(this, "Service Stopped", Toast.LENGTH_SHORT).show(); 
     Intent intent = new Intent(this, TestService.class); 
     bindService(intent, m_serviceConnection, BIND_AUTO_CREATE); 
     super.onDestroy(); 
    } 

    private boolean isNetworkConnected() { 
     ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
     return (cm.getActiveNetworkInfo() != null); 
    } 

    private void addNotification(String s, int i) { 
     NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) 
       .setSmallIcon(R.drawable.ic_launcher) 
       .setContentTitle("Lol Stalker") 
       .setContentText(
         "Notification text"); 

     Intent resultIntent = new Intent(this, FriendProfileActivity.class); 
     resultIntent.putExtra(Constants.FRIEND_NUMBER, i); 
     try { 
      resultIntent.putExtra(Constants.JSON, new startFriends().execute(prefs.getInt(Constants.PREF_FRIEND_ID + i, 0)) 
        .get()); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (ExecutionException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     // Because clicking the notification opens a new ("special") activity, 
     // there's 
     // no need to create an artificial back stack. 
     PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, 
       PendingIntent.FLAG_UPDATE_CURRENT); 

     mBuilder.setContentIntent(resultPendingIntent); 
     // Sets an ID for the notification 
     int mNotificationId = 001; 
     // Gets an instance of the NotificationManager service 
     NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
     // Builds the notification and issues it. 
     mNotifyMgr.notify(mNotificationId, mBuilder.build()); 

    } 

    private class startFriends extends AsyncTask<Integer, Integer, String> { 

     @Override 
     protected String doInBackground(Integer... params) { 
      HttpClient client = new DefaultHttpClient(); 
      String geturl = "apiurl.com"; 
      HttpGet get = new HttpGet(geturl); 
      HttpResponse responseGet = null; 
      String response = null; 
      try { 
       responseGet = client.execute(get); 
       HttpEntity resEntityGet = responseGet.getEntity(); 
       response = EntityUtils.toString(resEntityGet); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

      return response; 
     } 
    } 
} 

所以基本上,我想了解創建是使總在設備的後臺運行一個後臺服務,在執行時重新啓動。該服務執行一個asynctask,如果存在網絡連接,則每X秒發出一次http呼叫,並在條件滿足時顯示通知。但是它滯後太多,導致應用程序無法使用。如何解決這個問題?

+0

也許[此問題](http://stackoverflow.com/questions/21507967/skipped-147-frames-the-application-may-be-doing-too-much-work-on-its-main-threa )會有幫助嗎? – merlin2011

+0

你有沒有考慮過使用alarmmanager? –

回答

1

您對異步任務的execute()調用.get()。因爲它不再是異步的。除去.get()並將以下代碼行放在異步任務的onPostExecute中。

爲什麼使用一個處理程序作爲中間和一個額外的異步任務,你可以在你的線程中完成所有任務?

+0

或者採用[Async Callback](https://gist.github.com/ed-george/8097940a2b2a55d036c5)方法 –

0

正如我所看到的,你正在做一個處理程序中的大部分工作,並且根據定義,handleMessage在主線程上運行。

相關問題