How do I start a service in a new thread? - android

How do I start my service in a new thread. I looked on other questions but it dint work for me. What changes do I need to make in my service when normally running and when running in a separate thread?

Rename your public void onStart(final Intent intent, final int startId) method to _onStart and use this new onStart implementation:
#Override
public void onStart(final Intent intent, final int startId) {
Thread t = new Thread("MyService(" + startId + ")") {
#Override
public void run() {
_onStart(intent, startId);
stopSelf();
}
};
t.start();
}
private void _onStart(final Intent intent, final int startId) {
//Your Start-Code for the service
}
For API Levels 5 and Above
public void onStart(Intent, int) was deprecated at API level 5. This should be replaced with public int onStartCommand(Intent, int)
#Override
public int onStartCommand(final Intent intent, final int startId){
//All code from 'onStart()' in above placed here as normal.
}
private void _onStart(final Intent intent, final int startId) {
//Your Start-Code for the service
}

I do not think you can start your service in a new thread, but what you can do is start a new thread in your service.
This is because like the activity, the service has life cycle methods that run on the main thread.
So your service will run on the main thread but it will do the heavy lifting on a new thread that it creates when ever it needs to.
I hope it helps..

Citing from http://developer.android.com/reference/android/app/Service.html
"Note that services, like other application objects, run in the main thread of their hosting process. This means that, if your service is going to do any CPU intensive (such as MP3 playback) or blocking (such as networking) operations, it should spawn its own thread in which to do that work. More information on this can be found in Processes and Threads. The IntentService class is available as a standard implementation of Service that has its own thread where it schedules its work to be done."

In my project, i have someone like this and it's work:
Thread welcomeThread = new Thread() {
#Override
public void run() {
try {
super.run();
while (isMyServiceRunning() != true) {
sleep(100);
}
} catch (Exception e) {
System.out.println("EXc=" + e);
} finally {
Intent i = new Intent(getApplicationContext(), MainPage.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
}
};
welcomeThread.start();

Related

Multiple Services on Multiple Threads Lifecycle

These methods are implemented in a class extending Service. A new service is started every time a button is pressed.
If the button is pressed once, LogCat outputs what I expect, which includes a final output of "Service onDestroy." However, when the button is pressed twice, the second time before the first service ended, "Service onDestroy." displays only once when the first service is done, and the second service prints out the rest of "Service Running" logs but not "Service onDestroy."
Can anyone tell me why? Thank you!
public int onStartCommand(Intent intent,int flags, int startId) {
Log.i(TAG,"Service onStartCommand " + startId);
final int currentId = startId;
Runnable r = new Runnable() {
public void run() {
for (int i = 0; i < 3; i++) {
long endTime = System.currentTimeMillis() + 10*1000;
while (System.currentTimeMillis() < endTime) {
synchronized(this) {
try {
wait(endTime - System.currentTimeMillis());
}catch (Exception e) {
}
}
}
Log.i(TAG,"Service running");
}
stopSelf();
}
};
Thread t = new Thread(r);
t.start();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG,"Service onBind");
return null;
}
#Override
public void onDestroy() {
Log.i(TAG,"Service onDestroy");
}
In the guide for Services they use don't use stopSelf() but stopSelf(startId) when extending Service. The first stopSelf() propably stops both executions of your Service.
See here: http://developer.android.com/guide/components/services.html
Edit: Also a service is only created and destroyed once even when there are several executions of it running it is still a single service. In your case (a Bound Service) it will only be destroyed when the last excecution finishes. For logging every excecution ending you could try to override the stopSelf(int startId) method.

Android not able to stop service

In my app i am using a Service that periodically checks if there is a new personal message for the logged in user.
The service is started if the user enables the notification feature. Now if the user disables the notification feature i would like to stop the service.
I try to stop the service with the following lines of code.
Intent service = new Intent(getApplicationContext(), MessageService.class);
stopService(service);
The problem is that the service doesn't stop. It goes on working.
Here you can see my message service.
public class MessageService extends Service {
private int intervall;
public MessageService(){
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent,flags,startId);
Bundle intentData = intent.getExtras();
if(intentData != null) {
this.intervall = intentData.getInt("intervall");
}
final Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// async task for calling api otherwise we get an exeception here
new ServiceMessagesTask().execute(MessageService.this);
}
};
new Thread(new Runnable(){
public void run() {
while(true)
{
try {
Thread.sleep(intervall); // repeat after given intervall
handler.sendEmptyMessage(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
I have an activity where the user can edit his preferences. There it is also possible to activate the notification feature.
The notification service is started or stoped in the savePreferences() method:
public void savePreferences(View button) {
EditText login = (EditText)findViewById(R.id.txtbLogin);
EditText password = (EditText)findViewById(R.id.txtbPassword);
CheckBox enableNotification = (CheckBox) findViewById(R.id.cbNotifications);
Spinner spinner = (Spinner) findViewById(R.id.notificationInterval);
if(!login.getText().equals("") && !password.getText().equals("")){
Map<String, Object> preferences = new HashMap<String, Object>();
preferences.put("document_type", CouchbaseHelper.CB_VIEW_USER_PREFERENCES);
preferences.put("login", login.getText().toString());
preferences.put("password", password.getText().toString());
if(enableNotification.isChecked()){
preferences.put("enableNotification", true);
} else {
preferences.put("enableNotification", false);
}
preferences.put("notificationInterval", this.notificationInterval);
CouchbaseHelper couchbaseHelper = new CouchbaseHelper(getApplicationContext());
String documentId = couchbaseHelper.createDocUserPreferences(preferences);
couchbaseHelper.closeDb();
// start notification service if enabled
if(enableNotification.isChecked()){
Intent service = new Intent(getApplicationContext(), MessageService.class);
service.putExtra("intervall", Integer.valueOf(this.notificationInterval)*60*1000);
startService(service);
} else {
// TODO: this is not working!!! service doesnt stop
// try to stop running service
if(isMyServiceRunning()){
Intent service = new Intent(getApplicationContext(), MessageService.class);
stopService(service);
}
}
}
finish();
Intent main = new Intent(Preferences.this, Main.class);
startActivity(main);
}
I'm afraid you really don't get what a service is, service is just a component that do not require UI and is not linked to an activity life cycle, hence it runs in background, BUT background doesn't necessarily means in a separate thread, actually the service runs in the main thread, now that's one thing, killing a service doesn't mean you are killing all the working threads you create within, and in your code you are creating a Thread that is looping forever, that thread although created in the service is not linked in any way to the service life cycle.
So, if you want to stop the thread, get a reference to the thread you are creating in the startCommand method and in the onDestroy method just stop it, instead of having a while(true) validation, go for a flag and just change it to false in the onDestroy so it will stop the thread you created when started the service.
Regards!

Android stop service when ThreadPoolExcutor completed

I have a Service run independently with activity using startService(). This service handle many requests from activity and create Callable then add into ThreadPoolExecutor. It looks like this:
private ExecutorService requestExecutor;
private CompletionService<Result> requestHandleService;
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
// Create new Request Task and submit
Callable<Result> request = new Callable<Result>(){
public Result call() throws Exception {
}
};
requestHandleService.submit(task);
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy(){
super.onDestroy();
Log.d(TAg,"onDestroy service");
try{
if(requestExecutor!= null){
requestExecutor.shutdown();
}
}catch(Exception ex){
Ln.e(ex);
}finally{
requestExecutor= null;
requestHandleService= null;
}
}
The problem is that I want this Service run independently and parallel with activity. So activity can't control when to stop it. It should only stop when all tasks finished.
I know there is a way to wait for ThreadPool complete, but this can't work for me, because I don't need to keep the list requests. When this service receive request from activity, it should create new a task and submit immediately in onStartCommand.
Is there any way to solve this?
Have you checked out IntentService, this is sort of what this type of service does. If you need the multiple threads then you could wrap the tasks you submit with a check for the Queue used by the ThreadPool to see if it is empty, and if so, shutdown the service and the threadpool.
Callable is just an interface, so just make a callback out of it.
#Override
public void onCreate() {
mHandler = new Handler();
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
// Create new Request Task and submit
Callable<Result> request = new Callable<Result>(){
public Result call() throws Exception {
Result result = // ... mRealTask.call();
mHandler.postDelayed(queueCheck, 300);
return result;
}
};
requestHandleService.submit(task);
return super.onStartCommand(intent, flags, startId);
}
Runnable queueCheck = new Runnable() {
public void run() {
if (requestExecutor.getQueue().isEmpty()) {
stopService(new Intent(this, getClass()));
mHandler.removeCallbacks(this);
}
}
};

How to obtain information from onHandleIntent (Android)

I´m working on my IntentService, in which I generate values in a loop. In overriden methods onStartCommand() and onDestroy(), there is possible to display a message using Toast. I would like to use Toast also in onHandleIntent(), but it´s not working. I know there are better ways (files, attributes etc.) to display values, but I need these values immediately, when they are created. Not in the end (only for control, if it´s working properly). Please, can you help me identify the problem? Thanks in advance.
public class HelloIntentService extends IntentService {
public HelloIntentService() {
super("HelloIntentService");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent,flags,startId);
}
#Override
protected void onHandleIntent(Intent intent) {
long endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}}
#Override
public void onDestroy()
{
Toast.makeText(this, "Service is being destroyed now.", Toast.LENGTH_SHORT).show();
}
}
onHandleIntent runs on a separate thread in the background per the source code and therefore does not have any ability to update the UI. I would suggest using logging statements, rather than Toasts to display your information:
Log.d("HelloIntentService","service starting");

related to threads of services in android

the service is started by a single activity 4 times, how many threads are created by a service? And if service is started by 4 different activities then how many threads are created? Which function must be implemented inside a service inherited from intentService? how many threads are required to create inside this function?
public class HelloService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
long endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
#Override
public void onCreate() {
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}
the service is started by a single activity 4 times, how many threads are created by a service?
Depends. Your Service creates a new thread in onCreate, so if it's never killed then you'll only have 1 thread created. If somehow it did get killed, you would end up with one for every time you started your Service.
And if service is started by 4 different activities then how many threads are created?
Same as above.
Which function must be implemented inside a service inherited from intentService?
You might try reading the docs for IntentService, you'd find you want to implement onHandleIntent.
how many threads are required to create inside this function?
Zero.

Categories

Resources