我如何从后台服务更新Android活动中的信息
我试图创build一个简单的Android应用程序,它具有一个ActivityList的信息,当应用程序启动时,我打算启动一个将不断计算数据的服务(它将会改变),我希望ActivityList与该服务正在计算的应用程序的生活数据。
我如何设置我的活动来监听服务? 这是解决这个问题的最好方法吗?
例如,如果您想象一个股票价格列表 – 数据将被定期更改,并需要与(不断)计算/获取数据(在我的情况下)服务同步。
提前致谢
我如何设置自己的活动来监听服务? 这是解决这个问题的最好方法吗?
我有三个主要的select,
-
轮询。 该
Activity
定期向Service
询问最新数据。 恕我直言,这个选项很糟糕,但这当然是可能的。 -
callback。 根据jax的回答,
Activity
注册一个callback对象(“观察者”)。Service
在数据更改时调用callback方法,进而更新UI。 你可以在这里看到一个使用Service
的例子。 -
广播
Intents
。Service
通过sendBroadcast()
在数据更改上广播一个Intent
。 该Activity
使用registerReceiver()
注册BroadcastReceiver
,并且BroadcastReceiver
被通知传入的广播。 这会触发Activity
从Service
加载最新的数据,或者只是为了从广播Intent
获取最新的数据。 你可以在这里看到一个使用这个技术的例子。
这听起来像是观察者模式的一个很好的候选人。 基本上你的活动(观察者)将注册自己的后台服务(Observable),你可以从你的活动推或拉数据。 您的观察员在这种情况下将是您的活动,而Observable将是您的服务。
如果您对devise模式一无所知购买“头一个devise模式”,它很容易阅读,并充满了伟大的信息。
PS:我正在阅读。
您将有一个后台线程运行,计算列表中的更改。 此线程现在需要通知GUI该列表已更新的可能性。
你可以使用某种ArrayAdapter来获取数据到ListView中。 每次调用此方法时,ArrayAdapter都有一个名为adpater.notifyDataSetChanged()的方法,适配器将看到相应的数据已更改,然后通知列表视图,以便在下一次更新时进行更新。
您需要使用bindService()将活动与正在运行的服务绑定并与其通信。
public class BindingActivity extends Activity { YourService mService; boolean mBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onStart() { super.onStart(); // Bind to Your Service Intent intent = new Intent(this, YourService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // Unbind from the service if (mBound) { unbindService(mConnection); mBound = false; } } /** Called when a button is clicked (the button in the layout file attaches to * this method with the android:onClick attribute) */ public void onButtonClick(View v) { if (mBound) { // Call a method from your Service. // However, if this call were something that might hang, then this request should // occur in a separate thread to avoid slowing down the activity performance. int num = mService.getRandomNumber(); Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show(); } } /** Defines callbacks for service binding, passed to bindService() */ private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className, IBinder service) { // We've bound to the running Service, cast the IBinder and get instance LocalBinder binder = (LocalBinder) service; mService = binder.getService(); mBound = true; } @Override public void onServiceDisconnected(ComponentName arg0) { mBound = false; } }; }
和你的服务如:
public class LocalService extends Service { // Binder given to clients private final IBinder mBinder = new LocalBinder(); // Random number generator private final Random mGenerator = new Random(); /** * Class used for the client Binder. Because we know this service always * runs in the same process as its clients, we don't need to deal with IPC. */ public class LocalBinder extends Binder { LocalService getService() { // Return this instance of LocalService so clients can call public methods return LocalService.this; } } @Override public IBinder onBind(Intent intent) { return mBinder; } /** method for clients */ public int getRandomNumber() { return mGenerator.nextInt(100); } }
我真的很想知道为什么没有人提到一个使用任何库的EventBus的简单方法。 这当然是如果你不使用RX。 我个人最喜欢的是GreenRobot的EventBus。 https://github.com/greenrobot/EventBus
只需几行代码,不需要任何接口。 发一个事件,并听取它在任何你想要的。 它是分离的,它是线程安全的,它不会崩溃你的应用程序。