redrom
redrom

Reputation: 11632

Android : How to Run method in service on different thread?

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

Answers (3)

Tafveez Mehdi
Tafveez Mehdi

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

Mina Wissa
Mina Wissa

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

Droidman
Droidman

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

Related Questions