-1

I am coding an Android app using Android Studio.

My service class takes the values from the main activity class when starting the service.

However, when I reassign the values in the main activity, the change is not applied to the value in the service. Then, I tried to start a new service every time after reassigning the values, but it makes two services run at the same time.

Therefore, I would like to know if is there any way to remove the previous service when I start the new one. I am not sure if onDestroy() can do what I want. As far as I tried, I still can not make it.

This is the service class code:

public class ForegroundService extends Service {

double x1 = MainActivity.x1;
double y1 = MainActivity.y1;
double radius_ = MainActivity.radius_;
int k = MainActivity.k;

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    new Thread(
            new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        Log.e("Service", "Running " + String.valueOf(x1));
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
    ).start();
    return super.onStartCommand(intent, flags, startId);
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

}

After reassign x1, it shows two x1 value every one second:

E/Service: Running 35.6761919

E/Service: Running 35.4436739

Settasit7
  • 31
  • 2
  • 2
    "but it makes two services run at the same time" -- no, it does not. Services are natural singletons; there will be either zero or one instance of a given service running at any given time. Bear in mind that very few apps nowadays need a service at all; you might wish to reconsider having one in the first place. – CommonsWare Oct 28 '22 at 00:04
  • @CommonsWare I've just edited the question, hope you don't mind helping me understand the problem. I don't understand if the first service was gone, why it keeps printing two values of x1 every one second. – Settasit7 Oct 28 '22 at 03:51
  • You create a `Thread` on `onStartCommand()`. You do nothing to clean up that `Thread` in `onDestroy()`. So, that `Thread` continues to exist and do its work after the service is destroyed. – CommonsWare Oct 28 '22 at 11:26
  • Could you please suggest me the way to clean up the previous Thread after I stopService() and startSevice()? – Settasit7 Oct 30 '22 at 06:32
  • I recommend getting rid of the `Service` entirely. It is highly unlikely that you need one. – CommonsWare Oct 30 '22 at 11:41

1 Answers1

0

Your Service is never shut down. When you start it the first time from the Activity by calling startService(), the Service instance is created and this will initialize the values of x, y, k, etc. from MainActivity and onStartCommand() is called. You then start a thread that counts and logs. This thread runs forever (until Android kills off the OS process hosting your app). If you now do something in your Activity that changes the values of xc, y, k, etc. and then calls startService() again, this doesn't start another Service instance. Your Service is already running. So it just calls onStartCommand() again. This starts another thread that counts and logs. Now you have 2 threads that are counting and logging.

Also, it is bad practice to have a Service copy values from an Activity like this. It is better to put these values in the Intent you pass to startService() as "extras". You can then access these values in onStartCommand() as the Intent is passed through as a parameter to onStartCommand().

David Wasser
  • 93,459
  • 16
  • 209
  • 274
  • I tried using putExtra() in MainActivity, but it says getExtra() is deprecated. How to fix this? – Settasit7 Oct 30 '22 at 06:30
  • `putExtra()` and `getExtra()` are definitely not deprecated. Please edit your question and show what you did and what the problem is. You can definitely put data in an `Intent` using "extras" – David Wasser Oct 30 '22 at 11:09
  • Sorry, I mean I tried to add this in Foreground.class `Intent receiveIntent = getIntent();` `x1 = receiveIntent.getDoubleExtra("x1", x1);` but getIntent(); is deprecated. – Settasit7 Oct 30 '22 at 15:44
  • The `Intent` is passed as a parameter to `onStartCommand()`. Where are you trying to call `getIntent()`?? – David Wasser Oct 30 '22 at 17:57
  • In ForegroundService.class – Settasit7 Oct 30 '22 at 18:14
  • There is no `getIntent()` method in `Service`. Anyway, the `Intent` with the "extras" you have access to in `onStartCommand()` as a parameter. Get your "extras" from there. – David Wasser Oct 30 '22 at 18:42
  • Okay, now I can receive values from MainActivity writing this is Service. `String X1 = intent.getStringExtra("x1");` `String Y1 = intent.getStringExtra("y1");` `x1 = Double.parseDouble(X1);` `y1 = Double.parseDouble(Y1);` But I think the values will be sent only when startService right? Is there any way the link the values between MainActivity and Service all the time without startService again? – Settasit7 Oct 30 '22 at 20:22
  • The simple way is to put them in `static` variables. These can be accessed from anywhere. This, however, is a hack and isn't recommended. I don't know your requirements. Normally you would use something like `LiveData` for this, you can read about it here: https://developer.android.com/topic/libraries/architecture/livedata – David Wasser Oct 30 '22 at 21:30
  • You can also use bound services and AIDL and have your `Activity` bind to the `Service` and then call methods in the `Service` to update the values, but you would need to explain i more detail what you are trying to accomplish. – David Wasser Oct 30 '22 at 21:31