2014-07-11 20 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在主线程上运行。

相关问题