问题
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?
回答1:
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 Activity
s 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 Activity
s 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 ContentProvider
s. 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 ContentProvider
s.
回答2:
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.
回答3:
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
.
回答4:
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.
来源:https://stackoverflow.com/questions/28785346/update-activity-data-from-service-when-its-paused