Using Localbroadcast to achieve a cross-activity MVVM

Source: Internet
Author: User

Problem

A problem was encountered in the work:
Encapsulates an activity group that performs similar business a, but a small portion of the copy, picture is different, and requires that, during the execution of this group of activities, other businesses running in the background can modify the display at any time (or at the time of business a callback).
The less elegant options are:
-a reference to the activity passed in the callback. This limits the timing of the changes.
-Register the current activity in a single case and expose the corresponding modification interface on the activity. This is prone to memory leaks and requires other businesses to understand the various UI configurations/naming in Business a

In fact, this is a cross-activity MVVM problem, where both sides define good one model, and business A reads only the model content and works on the VM layer and the V layer. Other businesses only need to understand the model definition, hold the model and modify it.

The code has a binding function model
 Public  class Config {     Public Static FinalString Action_config_change ="Gt.research.androidbase.ACTION_CONFIG_CHANGE"; Public Static FinalString Key_changed_parts ="Key_changed_parts";Private intMId;//just for convenient    PrivateAtomicboolean mhascomsumed =NewAtomicboolean (true);//for Multithreading    Private Finalthreadlocal<arraymap<string, object>> mtransactionmap =NewThreadlocal<> ();PrivateLocalbroadcastmanager Mbroadcastmanager;//model    Private Finalarraymap<string, object> mconfigs =NewArraymap<> (); Public Config(intID) {mId = ID; }//multiple Changes     PublicConfigBeginTransaction(Context context) {arraymap<string, object> map = Mtransactionmap.get ();if(NULL= = map) {map =NewArraymap<> (); } map.clear ();return  This; } PublicConfigCommit(FinalContext context) {Finalarraymap<string, object> map = Mtransactionmap.get ();if(NULL= = map) {return  This; }//for multi-threadingConfigmanager.getinstance (). Runonuithread (NewRunnable () {@Override             Public void Run() {mconfigs.putall (map);            Notifychange (context, (string[)) Map.keyset (). ToArray ()); }        });return  This; } PublicConfigSet(FinalContext Context,FinalString name,FinalObject object) {configmanager.getinstance (). Runonuithread (NewRunnable () {@Override             Public void Run() {Mconfigs.put (name, object);            Notifychange (context, name); }        });return  This; } PublicObjectGet(context context, String name) {//constrain on A        if(Thread.CurrentThread ()! = Looper.getmainlooper (). GetThread ()) {Throw NewRuntimeException ("Wrong Thread"); }returnMconfigs.get (name); }//kvo    PrivateConfigNotifychange(context context, String ... names)        {Localbroadcastmanager Broadcastmanager = Getbroadcastmanager (context); Intent Intent =NewIntent (Action_config_change + mId); Intent.setpackage ("Gt.research.androidbase");        Intent.putextra (key_changed_parts, names);        Broadcastmanager.sendbroadcast (Intent); Mhascomsumed.set (false);return  This; }PrivateLocalbroadcastmanagerGetbroadcastmanager(Context context) {if(NULL= = Mbroadcastmanager) {Mbroadcastmanager = localbroadcastmanager.getinstance (context); }returnMbroadcastmanager; } Public Boolean shouldupdate() {return!mhascomsumed.getandset (true); } PublicString[]Getallnames() {return(string[]) Mconfigs.keyset (). ToArray (); }}
Public memory space
 Public  class configmanager {    Private Static volatileConfigManager sinstance; Public StaticConfigManagergetinstance() {if(NULL= = Sinstance) {synchronized(Configmanager.class) {if(NULL= = sinstance) {sinstance =NewConfigManager (); }            }        }returnSinstance; }Private ConfigManager() {    }Private FinalSparsearray<config> Mconfigs =NewSparsearray<> ();PrivateHandler Mhandler =NewHandler (Looper.getmainlooper ()); PublicConfigGetConfig(intID) {synchronized(Mconfigs) {Config config = mconfigs.get (id);if(NULL= = config) {config =NewConfig (ID); } mconfigs.put (id, config);returnConfig }    } Public void Runonuithread(Runnable Runnable)    {mhandler.post (runnable); }}
Business A
 Public  class main2activity extends appcompatactivity {    PrivateTextView MText;Private intMId;PrivateString maction;//kvo    PrivateBroadcastreceiver Mconfigreceiver =NewBroadcastreceiver () {@Override         Public void OnReceive(context context, Intent Intent) {if(Maction.equals (Intent.getaction ()))                {string[] changedparts = Intent.getstringarrayextra (config.key_changed_parts); Config config = configmanager.getinstance (). GetConfig (MId);if(Config.shouldupdate ())                {updateviews (changedparts, config); }            }        }    };@Override    protected void onCreate(Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate);        Setcontentview (r.layout.activity_main2);        MText = (TextView) Findviewbyid (R.ID.TEXT2); MId = Getintent (). Getintextra (mainactivity.key_id,-1);//a unique action just for this ActivityMaction = Config.action_config_change + mId;if(-1= = MId) {return; } localbroadcastmanager.getinstance ( This). Registerreceiver (Mconfigreceiver,NewIntentfilter (maction)); Config config = configmanager.getinstance (). GetConfig (MId);//fetch all missed changes        if(Config.shouldupdate ())        {Updateviews (config.getallnames (), config); }    }@Override    protected void OnDestroy() {Super. OnDestroy (); Localbroadcastmanager.getinstance ( This). Unregisterreceiver (Mconfigreceiver); }Private void updateviews(string[] changedparts, config config) {String key = changedparts[0]; String value = (string) config.get ( This, key);    Mtext.settext (value); }}
Other business
 Public  class mainactivity extends appcompatactivity {     Public Static FinalString key_id ="id";Private intMId;@Override    protected void onCreate(Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate);        Setcontentview (R.layout.activity_main); Findviewbyid (R.id.text). Setonclicklistener (NewView.onclicklistener () {@Override             Public void OnClick(View v) {mId = Math.Abs (NewRandom (System.currenttimemillis ()). Nextint ()); Intent Intent =NewIntent (mainactivity. This, Main2activity.class);                Intent.putextra (key_id, mId); StartActivity (Intent);NewThread () {@Override                     Public void Run() {Try{Thread.Sleep ( +); Configmanager.getinstance (). GetConfig (MId). Set (mainactivity. This,"Lala","DLFJLAJF"); }Catch(Interruptedexception e)                        {E.printstacktrace ();            }}}.start ();    }        }); }

Using Localbroadcast to achieve a cross-activity MVVM

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.