简体   繁体   中英

One Service Multiple Activities in Android

I have a service and 3 activities. The service is started in the first activity. Now when I move to the second activity and pressing on some button, I want to send a data to the service.

so in the second activity, inside the click listener I did the following:

 Intent service = new Intent(MyService.class.getName()); 
 service.putExtra("dataToSend",data.toString());
 startService(service);

but the method onStartCommand inside the service, doesn't get called..

Also, I want to create this service to work with multiple activities. I mean each activity will be able to send a data to this service and get a data from it.

Hi you need to bind your running service to activity you need to access it again. Following code snippets you can used as a reference

@Override
protected void onStart() {
    super.onStart();
    Intent mIntent = new Intent(this, MyService.class);
    bindService(mIntent, mConnection, BIND_AUTO_CREATE);
};

ServiceConnection mConnection = new ServiceConnection() {

    public void onServiceDisconnected(ComponentName name) {
        mBounded = false;
        myService= null;
    }

    public void onServiceConnected(ComponentName name, IBinder service) {
        // Toast.makeText(context, "Service is connected", 1000).show();

        mBounded = true;
        LocalBinder mLocalBinder = (LocalBinder) service;
        myService= mLocalBinder.getServerInstance();

      //now you are able to access any method in service class 
    }
};

QUESTION
I want to create this service to work with multiple activities. I mean each activity will be able to send a data to this service and get a data from it.

You don't have to do nothing with your Service . Services remain the same if they are not destroyed, that means all your Activities will be able to access to it's data .

PROBLEM

but the method onStartCommand inside the service, doesn't get called..

WHY
As long as your service has started, the onStartCommand is not called each time:

onStartCommand

Called by the system every time a client explicitly starts the service by calling startService (Intent), providing the arguments it supplied and a unique integer token representing the start request.

startService

Request that a given application service be started.

SOLUTION
call the events you need in onRebind method:

Called when new clients have connected to the service, after it had previously been notified that all had disconnected in its onUnbind(Intent). This will only be called if the implementation of onUnbind(Intent) was overridden to return true.

Hey call your service with below intent

 Intent mIntent = new Intent(this, MyService.class);

service.putExtra("dataToSend",data.toString());

 startService(mIntent);

in your case you are passing service class name and that will become action to your intent. So service won't start.

onstartCommand will call every time when you call startService and you can get data from intent which passed as extra.

To receive data from service to your activity. you can broadcast data from service and register broadcast in your activities

or

you can use binding mechanism

this what i did to make different activities to send and receive data from service

 public class SensorsActivity extends AppCompatActivity {
BluetoothService mService;
boolean mBound = false;

String valueReceived;
protected void onStart() {
    super.onStart();
    Log.v("STATE", "onStart() is called");
    // Bind to BluetoothService
    if (!mBound) {
        Intent intent = new Intent(this, BluetoothService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sensors);

    LocalBroadcastManager.getInstance(SensorsActivity.this).registerReceiver(mMessageReceiver,
            new IntentFilter("in.purelogic.simsonite.REQUEST_PROCESSED"));
}

private ServiceConnection mConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName className,
                                   IBinder service) {
        // We've bound to LocalService, cast the IBinder and get LocalService instance
        BluetoothService.LocalBinder binder = (BluetoothService.LocalBinder) service;
        mService = binder.getService();
        mBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
};

//BroadCastReceiver to let the MainActivity know that there's message has been recevied
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        try {
            handleMessage(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
};

//The Message that comes from the service
private void handleMessage(Intent msg) throws Exception {
    Bundle data = msg.getExtras();
    valueReceived = data.getString("DATA");
    Log.e("recv2", valueReceived);

}

}

one possible solution but not the best is using sharedpreferences . you can use it as a massage Transmitter from your activity to your service.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM