you may know about Google Cloud Messaging
The problem is that when a gcm message triggers by the server, my application receives a bundle from google play services, this happen at GcmBroadcastReceiver.java
. Here i can send this data to other classes in order to append some info from the server.. well. I got stuck when i try to update, for example, some views in the UI thread.
HOW I CAN DO THIS?
Imagine that MainActivity.java
is the UI thread when i declare the views, etc.
I tried to create here a public static method which can be called directly by GcmBroadcastReceiver.java
by this way: MainActivity.*updateUI*(args..)
, but it throws this exception:
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Can anyone try to explain me this? i also know about asyncTask but i cant imagine how it works. I also find some pages explaining events that are fired by the UI thread it self like runnables that do some task in background. Im searching something like this:
MainActivity extends Activity{
...
protected void onCreate(Bundle blabla)..{
setContentView(R.layout.blabla);
registerSomeEvent(this);
}
private void handleEvent(Bundle ...){
... do stuff with the data provided in the UI thread
}
}
And here at GcmBroadcastReceiver
, when gcm push some data, trigger that magic event in order to perform updates at the UI thread with some views like ListViews
or TextView
You can use Handlers in your MainActivity in order to comunicate with UI Thread.
Communicating with the UI Thread
and in your non Activity class
One way is to use use LocalBroacastManager. For how to implement is, there is a great example on how to use LocalBroadcastManager?.
Your activity can register for this local broadcast. From the
GCMBroadcastReceiver
, you send a local broadcast when you receive something in GcmBroadcastReceiver. Inside yourActivity
you can listen to the broadcast. This way if the activity is in the forefront/is active, it will receive the broadcast otherwise it won't. So, whenever you receive that local broadcast, you may do the desired action if activity is open. This is like saying to the activity that "Hey Activity, I've received a message. Do whatever you want with it".If you want to do for the whole app, then you can make all your activities extend an abstract activity. And inside this abstract activity class you can register it for this 'LocalBroadcast'. Other way is to register for LocalBroadcast inside all your activities (but then you'll have to manage how you'll show the message only once).