Reputation: 1034
my usecase is (roughly) the following on first startup:
Now I want to display a progress bar while the service is busy. The problem is:
startService(new Intent(getApplicationContext(), UpdateDataService.class));
takes a very long time to "come back" to the UI thread. It seems to be a synchronized function (or not?). If a empty the service class the startService command is processed almost instant. It seems the UI thread waits for the Serice to handle its work, which does not make sense at all. I tried to start (as stupid as it may seem) to start the service a async task while displaying a progress bar in my UI thread. Weird enough this works sometimes. Othertimes I just get a white screen while my service is working and afterwards for a millisecond ma progressbar and then my UI.
Now my question: How do I start the service without blocking my UI?
public class MyClass extends TabActivity {
private ProgressDialog pd;
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = null;
//building some tabs here, setting some text views....
// starting service if does not exist yet
boolean serviceRunning = false;
final ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
for (final RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if ("aegir.mobile.UpdateDataService".equals(service.service.getClassName())) {
serviceRunning = true;
Log.i(MY_APP_TAG, "Service found.");
}
}
if (!serviceRunning) {
pd = ProgressDialog.show(this, "Loading...", "Setting up data.", true, false);
new StartServiceAsync().execute("");
}
}
private final Handler handler = new Handler() {
@Override
public void handleMessage(final Message msg) {
pd.dismiss();
}
};
public class StartServiceAsync extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(final String... params) {
// starting service
startService(new Intent(getApplicationContext(), UpdateDataService.class));
return null;
}
@Override
protected void onPostExecute(final String result) {
handler.sendEmptyMessage(0);
super.onPostExecute(result);
}
}
Upvotes: 4
Views: 5549
Reputation: 12685
please Use this code the easy way to do what you asked in question.
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent intent = null;
registerReceiver(dataUpdated, new IntentFilter("<FLAG>"));
//building some tabs here, setting some text views....
// starting service if does not exist yet
boolean serviceRunning = false;
final ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
for (final RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if ("aegir.mobile.UpdateDataService".equals(service.service.getClassName())) {
serviceRunning = true;
Log.i(MY_APP_TAG, "Service found.");
}
}
if (!serviceRunning) {
pd = ProgressDialog.show(this, "Loading...", "Setting up data.", true, false);
startService(new Intent(getApplicationContext(), UpdateDataService.class));
}
}
private BroadcastReceiver dataUpdated= new BroadcastReceiver() {
@SuppressLint("ShowToast")
@Override
public void onReceive(Context context, Intent intent) {
//<Your Process which you want when Service finishes a task >
pd.dismiss();
}
};
@Override
protected void onDestroy() {
unregisterReceiver(dataUpdated);
}
In Service when your Task will Complete call this Method
sendBroadcast(new Intent("<FLAG>"));
Upvotes: 0
Reputation: 36302
Either do your work in the AsyncTask
itself, use an IntentService
instead of a plain old Service
or start a thread from your Service
to do your work. A Service
in Android does not inherently use a different thread (IntentService
does to do its work).
Despite starting your Service
from an AsyncTask
, right now it seems the actual work is being performed in your UI thread.
Upvotes: 1
Reputation: 5183
I think you should just move the logic from the service to the doInBackground method in the async task. That's what async task are for, executing hard work giving you a simple way to interact with the UI. It's weird to call a service in the async task, is there any reason why you did that?
Upvotes: 1
Reputation: 234795
From the guide topic Services:
Caution: A services runs in the same process as the application in which it is declared and in the main thread of that application, by default. So, if your service performs intensive or blocking operations while the user interacts with an activity from the same application, the service will slow down activity performance. To avoid impacting application performance, you should start a new thread inside the service.
This doesn't change just because you call startService
from an AsyncTask.
Upvotes: 9