Update Activity data from service when its paused

2019-07-21 16:15发布

Lets say I have an activity that has a data object. It updates its gui component based on that object. Now lets say that it is paused ( OnPause is called) but not stopped or destoryed

Meanwhile , a push notification is received ( intentservice is started) and I need to update that object with the push notification object so I gui is updated when the app is resumed.

I thought about sending a broadcast to the activity so it can update its dataobject But I read somewhere that when activity is paused then broadcasts are not received.

What should I do in this case?

4条回答
疯言疯语
2楼-- · 2019-07-21 16:20

I thought about sending a broadcast to the activity so it can update its dataobject But I read somewhere that when activity is paused then broadcasts are not received.

What should I do in this case?

I think the resource of that information is incorrect, if you declare a receiver in onCreate and remove it at onDestroy you wont have any problems. What I mean is, first parse the push notification with your service and then send localBroadcast to the activity. It is as simple as you thought. then update your GUI at onRecieve method of your reciever.

查看更多
成全新的幸福
3楼-- · 2019-07-21 16:24

You should bind to the Service when the Activity starts. Then in onResume you can request updates that may have occurred while the activity was paused.

You may consider passing data to the activity through a callback to update variables in the activity while it is paused, but then you will need to update the UI in onResume.

Also consider that when your Activity is paused, it may get destroyed and re-created. You don't seem concerned with that scenario based on your question, but I thought it important to explain it. to handle any changes for this scenario, you would need to persist the data for the change. If you are persisting the data, then you don't need to bind to the Service you simply need to check the persistent data store in onResume.

EDIT:

In your comment you mention an IntentService which you cannot "bind" to. You have several options in this case (basically listed in order of preference). First, you can create a Service when your activity is created, then have the IntentService forward intents to that service. Second, you can have a Static variable in your Activity to allow the IntentService to access a shared data store. As mentioned previously, you can also persist the data (put in SharedPreferences, a file or a database. Last, you can use the Application class to store references to the data so that while your app is active, you can pass data.

查看更多
不美不萌又怎样
4楼-- · 2019-07-21 16:36

The hard but correct way to do this is to build your own custom ContentProvider for your app and update all data received from web services and push notifications to this ContentProvider. When the Activity comes back into the foreground, it updates itself with the new data provided by the ContentProvider.

It is hard because making a custom ContentProvider is a lot of work. It is the correct way because it is in conformance with the behavior of mobile applications and with the Android architecture: say a user activates a web-service or some computation-intensive task, and then dismisses the app; or say a push notification arrives and requires the app's data to be updated and displayed. In both cases, the app's Activitys may no longer be in the foreground, but a Service can be used to perform some non-UI operation. Now at the end of that operation, the Service makes changes to the data through the ContentProvider, and when the user activates the app again, the Activitys get their new data from the ContentProvider.

To quote the official tutorial:

Content providers are the standard interface that connects data in one process with code running in another process.

As a developer, you should always assume that the user may invoke an app at any time and dismiss it at any time. Irrespective of whether an Activity is in the foreground or not, the app's data needs to be correctly updated and maintained.

Google's own apps use custom ContentProviders. The Gmail app in particular makes use of its ContentProvider to get new emails when network connectivity is available and display emails offline. The Facebook, WhatsApp & Twitter Android apps also make use of ContentProviders.

查看更多
冷血范
5楼-- · 2019-07-21 16:39

You pretty much treat it as if the Activity was destroyed. You can't really assume that it won't happen once onPause is called.

If the object represents something that's persistent, then simply update the persistent portion of the object and retrieve it when the Activity resumes. If it represents a state of a Service for example, then bind to the service and update. If it's a database, then update the database then refresh the Activity onResume.

If it's a temporary object that's only valid through the life of an Activity, then you need to make something persistent that the Activity can check when it resumes. Something simple like a boolean variable in the "sharepreferences". In onResume, check for the object, if it exists, then retrieve object, then clear the object.

查看更多
登录 后发表回答