Reputation: 11632
I trying to do some long time operation in service which is started from the controller.
public void startDashboardBgService() {
Boolean isAppInForeground = Container.getInstance().isAppInForeground();
if (isAppInForeground) {
stopDashboardBgService();
context.startService(new Intent(context, DashboardService.class));
}
}
Then i calling long time operation method from the onStartCommand event.
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Logger.d("onStartCommand");
updateDashboardValues();
handler = new Handler();
context = this;
return mStartMode;
}
And here is the method which should to do work on the separated thread.
private Runnable runnableCode = new Runnable() {
@Override
public void run() {
List<Reminder> reminders = Reminder.getAllRemindersFromDB(context);
if (reminders.size() > 0) {
for (Reminder r : reminders) {
Logger.d(r.getMessage());
}
} else {
Logger.d("No reminders in table, dashboard cannot be updated");
}
}
};
private void updateDashboardValues() {
try {
Thread t = new Thread(runnableCode);
t.start();
} catch (Exception e) {
TrackingEventLogHelper.logException(e, Constants.Global.EXCEPTION,
Constants.ExceptionMessage.EXC_CANNOT_CANCEL_UNIQUE_ALARM_FOR_DASHBOARD_CHECK, true);
}
}
But when is the method called from activity (controller) UI is lagging and i getting following message.
Skipped 604 frames! The application may be doing too much work on its main thread.
How can i solve it please?
Many thanks for any advice.
Upvotes: 0
Views: 1453
Reputation: 456
Android Services by default, run on UI thread. If you have to do some heavy work you need to perform it on worker thread.
It would be better to use IntentService for long running operations, because using AsyncTask for long running operations is not recommended.
Upvotes: 1
Reputation: 10971
You can create a new Thread & a Runnable and wrap your method in it.
Or you can use an IntentService which takes care of running your methods in a worker thread automatically
Upvotes: 1
Reputation: 11608
Try running the code inside an AsyncTask
, see an example below. Note: you can parameterize it with any types you need.
Edit: example of how to pass parameters (Context
in this case) to the task.
new AsyncTask<Context, Void, Void>() {
//local fields
@Override
protected void onPreExecute() {
//runs on UI Thread
}
@Override
protected void onCancelled() {
/* runs on UI Thread instead of onPostExecute()
if cancel(boolean) was called */
}
@Override
protected void onProgressUpdate(Progress... values) {
//runs on UI Thread
}
@Override
protected Void doInBackground(Context... params) {
//background Thread - do heavy work here
Context c = params[0];
return null;
}
@Override
protected void onPostExecute(Void result) {
//runs on UI Thread
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mContext);
Upvotes: 2