如何将数据从活动传递到正在运行的服务

时间:2017-05-02 11:26:33

标签: android android-intent service pass-data

我想定期向服务器发送数据,我正在使用后台Service,但我希望在数据更新时发送,以及我在Activity中获得的更新数据并且Service正在后台运行..那么如何将数据传递给Service正在运行的Activity。使用Intent我只能在启动Service时发送一次数据。

Intent serviceIntent= new Intent(DriverActivity.this,demoService.class);
serviceIntent.putExtra("token", token);
startService(serviceIntent);

4 个答案:

答案 0 :(得分:4)

阅读这篇文章https://developer.android.com/guide/components/bound-services.html

例如,您可以使用Messanger

public class MessengerService extends Service {
    /** Command to the service to display a message */
    static final int MSG_SAY_HELLO = 1;

    /**
     * Handler of incoming messages from clients.
     */
    class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SAY_HELLO:
                    Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    /**
     * Target we publish for clients to send messages to IncomingHandler.
     */
    final Messenger mMessenger = new Messenger(new IncomingHandler());

    /**
     * When binding to the service, we return an interface to our messenger
     * for sending messages to the service.
     */
    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
        return mMessenger.getBinder();
    }
}

在您的ActivityFragment中,您可以通过以下方式发送数据:

public class ActivityMessenger extends Activity {
    /** Messenger for communicating with the service. */
    Messenger mService = null;

    /** Flag indicating whether we have called bind on the service. */
    boolean mBound;

    /**
     * Class for interacting with the main interface of the service.
     */
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            // This is called when the connection with the service has been
            // established, giving us the object we can use to
            // interact with the service.  We are communicating with the
            // service using a Messenger, so here we get a client-side
            // representation of that from the raw IBinder object.
            mService = new Messenger(service);
            mBound = true;
        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            mService = null;
            mBound = false;
        }
    };

    public void sayHello(View v) {
        if (!mBound) return;
        // Create and send a message to the service, using a supported 'what' value
        Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
        try {
            mService.send(msg);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

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

    @Override
    protected void onStart() {
        super.onStart();
        // Bind to the service
        bindService(new Intent(this, MessengerService.class), mConnection,
            Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        // Unbind from the service
        if (mBound) {
            unbindService(mConnection);
            mBound = false;
        }
    }
}

如果您不知道如何使用Message传递数据,请查看此答案https://stackoverflow.com/a/17929775

答案 1 :(得分:0)

最好的选择是将数据保存在硬盘上(例如SharedPreferences,database,...)。

活动已更新=>坚持存储=>调用服务

服务必须在发送数据之前从所选存储中读取数据。

答案 2 :(得分:0)

使用多线程代替它变得更容易,你将获得相同的功能。

 mHandler = new Handler();

    // Set a click listener for button
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mCounter = 0;
            /*
                Runnable
                    Represents a command that can be executed. Often used to run code in a
                    different Thread.

                Thread
                    A Thread is a concurrent unit of execution. It has its own call stack for
                    methods being invoked, their arguments and local variables. Each application
                    has at least one thread running when it is started, the main thread, in the
                    main ThreadGroup. The runtime keeps its own threads in the system thread group.

                    There are two ways to execute code in a new thread. You can either subclass
                    Thread and overriding its run() method, or construct a new Thread and pass a
                    Runnable to the constructor. In either case, the start() method must be
                    called to actually execute the new Thread.

            */
            mRunnable = new Runnable() {
                /*
                    public abstract void run ()
                        Starts executing the active part of the class' code. This method is
                        called when a thread is started that has been created with a class which
                        implements Runnable.
                */
                @Override
                public void run() {
                    // Do some task on delay
                    doTask();
                }
            };

            /*
                public final boolean postDelayed (Runnable r, long delayMillis)
                    Causes the Runnable r to be added to the message queue, to be run after the
                    specified amount of time elapses. The runnable will be run on the thread to
                    which this handler is attached. The time-base is uptimeMillis(). Time spent
                    in deep sleep will add an additional delay to execution.
            */
            mHandler.postDelayed(mRunnable, (mInterval));
        }
    }); //use minterval to be the period in ms eg:     private int mInterval = 4000;

答案 3 :(得分:0)

1.发送数据到服务Upto Lolipop版

Intent serviceIntent= new Intent(DriverActivity.this,demoService.class);
serviceIntent.putExtra("token", token);
startService(serviceIntent);
  1. 在服务类中检索数据:

     @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
    Toast.makeText(this, "Starting..", Toast.LENGTH_SHORT).show();
    Log.d(APP_TAG,intent.getStringExtra("token"));
    return "your flag";
    }