Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/205.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何将数据从活动传递到正在运行的服务_Android_Android Intent_Service_Pass Data - Fatal编程技术网

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

Android 如何将数据从活动传递到正在运行的服务,android,android-intent,service,pass-data,Android,Android Intent,Service,Pass Data,我想定期向服务器发送数据,我正在使用后台服务,但我想在数据更新时发送,并且在活动中获得更新的数据,并且服务正在后台运行。。那么,如何将数据从活动传递到正在运行的服务。使用Intent启动服务时,我只能发送一次数据 Intent serviceIntent= new Intent(DriverActivity.this,demoService.class); serviceIntent.putExtra("token", token); startService(serviceIntent);

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

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

最好的选择是将数据持久保存在硬盘上(例如,共享数据引用、数据库等)

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


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

使用多线程,这样会变得更容易,您也会获得相同的功能

 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;

1.将数据发送到Lolipop版本的服务

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

     @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";
    }
    
  • 阅读这篇文章

    例如,您可以使用
    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();
        }
    }
    
    活动
    片段
    中,您可以通过以下方式发送数据:

    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;
            }
        }
    }
    

    如果您不知道如何使用
    消息传递数据
    看看这个答案

    我的意见是使用事件总线或广播接收器。您可以使用广播接收器向运行中的服务发送数据,也可以使用
    startService()
    向运行中的服务发送任意次数的数据。如果
    服务已经启动,它不会启动
    服务,但会调用
    onStartCommand()
    ,其中包含
    Intent
    中的数据。可能与我在问题中提出的问题重复,我想通过使用Intent将数据发送到正在运行的服务,但我不能只发送一次。@TusharKotecha不正确。您可以通过调用
    startService()
    来向正在运行的
    服务发送数据。在
    服务
    中,将对正在运行的服务调用
    onStartCommand()
    。这当然是最简单的方法,尽管还有很多其他方法。@Rajasekhar如果我每次发送数据时都使用startService(),那么它会创建新线程或新服务吗?或者它会在设备上加载?基本上,您想说startService()和通过intent传递数据将把数据传递给正在运行的服务?这需要绑定到
    服务
    ,这比再次调用
    startService()
    来发送更多数据要复杂得多。否则这是一个完美的解决方案。@DavidWasser,是的。但对于服务,为了管理api调用,他应该在服务中创建工作线程。发送意图,通过startService在单独的线程中进行处理,这对于我和其他将来可能支持应用程序的程序员来说并不明确。如果在首次处理后使用IntentService,则应停止内容服务。所以,我认为,如果服务应该执行长时间运行的任务,并且可以在运行时接受数据,那么他应该使用绑定并通过messenger或一些自定义服务方法传递数据,但这也需要绑定。显然,
    IntentService
    不是正确的解决方案。这里您需要一个常规的
    服务
    ,您可以自己启动和停止。您完全没有理由不能或不应该使用
    startService()
    Intent
    传递给正在运行的
    服务。
    服务
    无论如何都应该启动一个后台线程来进行处理,因此您可以随时通过发送一个新的
    意图
    来控制
    服务。@Alexander Goncharenko,我想用start\u STICKY模式启动服务。使用此解决方案,我认为不会调用onStartCommand方法。我如何在您的解决方案中使用粘性模式?