简体   繁体   中英

Updating Activity UI component from Broadcast Receiver?

I have very basic ques. and it might be very simple but i am not getting it. I have an Activity where I am using some UI component. and I also have a broadcast receiver (registering from manifest) where I need to update some UI component of Activity class. Like -

    Class MyActivity extends Activity
     {

        onCreate(){

         //using some UI component lets say textview
           textView.setText("Some Text");
        }

       updateLayout()
       {
         textView.setText("TextView Upadated...");
       }
 }


Class broadCastReceiver
{

    onReceive()
    {
       //here I want to update My Activity component like 
       UpdateLayout();

    }

} 

For that- One solution is that make the updateLayout() method public static , and use that method in receiver class by activity reference . But I think, this is not the right way to do this.. Is there any proper way to do that?

Instead of registering a receiver in manifest, you can register and unregister it at runtime as follows:

Also make sure you register your receiver with correct Action in Intent Filter.

public class MyActivity extends Activity{

// used to listen for intents which are sent after a task was
// successfully processed
private BroadcastReceiver mUpdateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        new UpdateUiTask().execute();
    }
};

@Override
public void onResume() {        
    registerReceiver(mUpdateReceiver, new IntentFilter(
            YOUR_INTENT_ACTION));
    super.onResume();
}

@Override
public void onPause() {     
    unregisterReceiver(mUpdateReceiver);
    super.onPause();
}


// used to update the UI
private class UpdateUiTask extends AsyncTask<Void, Void, String> {

    @Override
    protected void onPreExecute() {

    }

    @Override
    protected String doInBackground(Void... voids) {
        Context context = getApplicationContext();
        String result = "test";
        // Put the data obtained after background task. 
        return result;
    }

    @Override
    protected void onPostExecute(String result) {
        // TODO: UI update          
    }
}  

}

Hope it helps.

If you really have to keep using BroadcastReceiver registered from AndroidManifest.xml then you could consider using event bus. There is one cool open source library Otto from Square .

It's implementing publisher/subscriber pattern very nicely. You will find many examples on the web how to use it, it's very simple. First of all check out the Otto's website

If you can register/unregister receiver directly from Activity then I would follow @Ritesh Gune answer.

I'd certainly recommend EventBus from GreenRobot

EventBus is an Android optimized publish/subscribe event bus. A typical use case for Android apps is gluing Activities, Fragments, and background threads together. Conventional wiring of those elements often introduces complex and error-prone dependencies and life cycle issues. With EventBus propagating listeners through all participants (eg background service -> activity -> multiple fragments or helper classes) becomes deprecated. EventBus decouples event senders and receivers and thus simplifies communication between app components. Less code, better quality. And you don't need to implement a single interface!

check out : https://github.com/greenrobot/EventBus

you can use ObservableEvent with extends Observable class.

public class ObservableEvent extends Observable {
public void setChanged(){
    super.setChanged();
}
}

Make singleton class notification center

public class NSNotificationCenter {

private HashMap<String, ObservableEvent> observables = new HashMap<String, ObservableEvent>();

/**
 * Lazy load the event bus
 */

public void addObserver(String notification, Observer observer) {
    ObservableEvent observable = observables.get(notification);
    if (observable == null) {
        observable = new ObservableEvent();
        observables.put(notification, observable);
    }
    observable.addObserver(observer);
}

public void removeObserver(String notification, Observer observer) {
    Observable observable = observables.get(notification);
    if (observable != null) {
        observable.deleteObserver(observer);
    }
}


public void postNotification(String notification, Object object) { 
        ObservableEvent observable = observables.get(notification);
        if (observable != null) {
            observable.setChanged();
            if (object == null) { 
                observable.notifyObservers();
            } else {
                observable.notifyObservers(object);
            }
        } 
}

}

just use to add observer for observing notify and for firing method use post notification

From the docs :

You can either dynamically register an instance of this class with Context.registerReceiver() or statically publish an implementation through the tag in your AndroidManifest.xml.

Register a receiver in Activity.onResume() implementation and unregister in Activity.onPause() .

public class MyActivity extends Activity
{
    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            MyActivity.this.broadcastReceived(intent);
        }
    };

    public void onResume() {
       super.onResume();
       IntentFilter intentFilter = new IntentFilter();
       // add action, category, data to intentFilter
       this.registerReceiver(this.mBroadcastReceiver, intentFilter);
    }

    public void onPause() {
       super.onPause();
       this.unregisterReceiver(this.mBroadcastReceiver);
    }

    public void broadcastReceived(Intent intent) {
       // Update the UI component here.
    }
}

You can use observer pattern-the activity registers itself in onResume() with the broadcast receiver to receive updates and in onPause() unregisters itself.

There are lot of material on net to learn observer pattern- http://en.wikipedia.org/wiki/Observer_pattern

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM