我为我的应用程序创建了一个后台服务,但它显示错误“在其主线程服务上做了太多工作”。而且它使应用程序滞后到无法使用的程度。那么,我的代码有什么问题呢?
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;
}
}
}
所以基本上,我想要创建的是创建一个始终在设备后台运行的后台服务,在执行时重新启动。该服务执行一个异步任务,如果有网络连接,则每隔 X 秒进行一次 http 调用,并在满足条件时显示通知。然而,它滞后太多,导致应用程序无法使用。如何解决这个问题?
最佳答案
您正在异步任务的execute() 上调用.get()
。因此它不再是异步的。删除 .get() 并将以下代码行放在异步任务的 onPostExecute 中。
为什么使用处理程序作为中间任务和额外的异步任务,您可以在线程中完成所有操作?
关于java - 如何解决我的后台服务中的 "doing too much work on its main thread service"错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24692902/