定期的にサーバーにデータを送信したいので、バックグラウンドService
を使用していますが、データが更新されたときに送信したいのですが、Activity
で取得した更新データとService
はバックグラウンドで実行されています。Service
から実行中のActivity
にデータを渡すにはどうすればよいですか。 Intent
を使用すると、Service
の開始時にデータを1回しか送信できません。
Intent serviceIntent= new Intent(DriverActivity.this,demoService.class);
serviceIntent.putExtra("token", token);
startService(serviceIntent);
この記事を読む 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();
}
}
また、Activity
またはFragment
では、次の方法でデータを送信できます。
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.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";
}
最良のオプションは、ハードドライブ(SharedPreferences、データベースなど)にデータを保持することです。
アクティビティが更新されました=>ストレージに永続化します=>サービスを呼び出します
サービスは、データを送信する前に、選択したストレージからデータを読み取る必要があります。
代わりにマルチスレッドを使用すると、はるかに簡単になり、同じ機能が得られます。
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;