Objective
When developing an app, frequently used activity and fragment, due to the ease of operation fragment more and more popular, so as to avoid the activity and fragment, fragment and fragment communication, We know that fragment and fragment cannot communicate directly, but instead communicate through activity. So there are several ways of communication between activity and fragment, and what are their advantages and disadvantages? A common activity and fragment several communication methods 1 through handle in the activity to create a handle mechanism instance, and then in the creation of fragment through the construction method to pass the handle instance in the past, So fragment can send data to the activity. However, the following disadvantages are as follows: (1) The coupling between activity and fragment increases; (2) The results of activity processing cannot be fed back to fragment; (3) The memory leakage risk is increased; 2 The disadvantage of using the static variable is clearly increased memory consumption; 3 Use broadcasts to register broadcasts in activity and fragment, so that communication can be achieved. Its disadvantage: (1) Poor performance, delay, the user experience will be poor; (2) The general use of the standard broadcast, a send, multiple receivers, overqualified, poor performance; (3) Code redundancy, (4) Limited data transmission, 4 Eventbus, Rxbus (commonly known as universal oil) Its use method reference official documents, Its advantages are simple and convenient to use, its shortcomings are also obvious: (1) Eventbus, rxbus its internal uses is the reflection mechanism, then its performance will be reduced; (2) Code maintenance difficult (unfamiliar project code of the new person is difficult to find out how the implementation method is called), (3) Data return difficulties, They are one-way pass; 5 Ordinary interface write an interface in fragment, let activity to implement this interface, through this interface to bind activity and fragment together, so activity and fragment communicate in real time, In fact, Google is recommended to do so, because each fragment write an interface, will cause code redundancy, if fragment less good, more words, activity implementation of multiple interfaces, it appears that the activity head is very large, and the name of the interface is also a problem; Universal interface If the basis of the 5 can solve the code redundancy, interface naming, we know that a function includes function name, function body, parameters, return value, then you can build a simple framework to achieve the above problem. 1 Building a base class
Public abstract class Function { /** method name */public String mfunctionname; Public Function (String funname) { this.mfunctionname = Funname; }}
2 Create None (have) parameters None (have) four classes
/** * no parameter no return value *
/** * parameter no return value *
/** * has a parameter return value *
/** * no parameter with return value *
3 Setting up the manager class
public class Functionmanager {private static Functionmanager instance = NULL; public static final String TAG = FunctionManager.class.getSimpleName () + "-------->"; /** container, which is used to store method names corresponding to methods name value, corresponds to the parameter return object */Private hashmap<string,functionwithparamwithresult> MFUNCTIONWITHP Aramwithresulthashmap = null; Private hashmap<string,functionwithparamonly> mfunctionwithparamsonlyhashmap = null; Private hashmap<string,functionwithresultonly> mfunctionwithresultonlyhashmap = null; Private hashmap<string,functionnoparamnoresult> mfunctionnoparamnoresulthashmap = null; Private Functionmanager () {mfunctionnoparamnoresulthashmap = new hashmap<> (); Mfunctionwithparamwithresulthashmap = new hashmap<> (); Mfunctionwithparamsonlyhashmap = new hashmap<> (); Mfunctionwithresultonlyhashmap = new hashmap<> (); }public static Functionmanager getinstance () {if (null = = Instance) {instance = new Functionmanager (); }return instance; }/** * Add no parameter no return value method * @return */public Functionmanager addfunction (Functionnoparamnoresult function) {mfunct Ionnoparamnoresulthashmap.put (function.mfunctionname,function); return this; }/** * Add a method with return value * @return */public Functionmanager addfunction (functionwithresultonly function) {mfunction Withresultonlyhashmap.put (function.mfunctionname,function); return this; }/** * Add Parameter method * @return */public Functionmanager addfunction (functionwithparamonly function) {MFUNCTIONWI Thparamsonlyhashmap.put (function.mfunctionname,function); return this; }/** * Add a method with the parameter return value * @return */public Functionmanager addfunction (Functionwithparamwithresult function) {MF Unctionwithparamwithresulthashmap.put (function.mfunctionname,function); return this; }/** * Call no return value no parameter method * @param funname */public void Invokenoall (String funname) throws Nullpointerexceptio n {if (textutils.iseMpty (Funname)) {LOG.E (TAG, "Funname is null!");} else {if (null! = Mfunctionnoparamnoresulthashmap) {Functionnoparamnoresult function = Mfunctionnoparamno Resulthashmap.get (Funname); if (null! = function) {function.function (); }else {log.e (TAG, "function is null!");}} else {throw new NullPointerException ("Mfunctionnoparamnoresulthashmap can not is null, please first init Functionmanager!) "); }}}/** * Call the method with parameters * @param funname */public <Param> void Invokewithparamonly (String Funn Ame,param Param) throws NullPointerException {if (Textutils.isempty (Funname)) {LOG.E (TAG, "Funname is null!"); }else {if (null! = Mfunctionwithparamsonlyhashmap) {functionwithparamonly<param> function = Mfunctionwithparamsonlyhashmap.get (Funname); if (null! = function) { Function.function (param); }else {log.e (TAG, "function is null!");}} else {throw new NullPointerException ("Mfunctionwithparamsonlyhashmap can not is null, please first init functionmanager!") ); }}}/** * Call method with return value * @param funname */public <Result> Result invokewithresultonly (String Funname, class<result> c) throws NullPointerException {if (Textutils.isempty (Funname)) {LOG.E (TAG, "funNa Me is null! ");} else {if (null! = Mfunctionwithresultonlyhashmap) {functionwithresultonly function = Mfunctionwithresulto Nlyhashmap.get (Funname); if (null! = function) {if (null! = c) {return C.cast (function.function ()); }else {return (Result) function.function (); }}else {log.e (TAG, "function is null!");}} else {throw new NullPointerException ("Mfunctionwithparamsonlyhashmap can not is null, please first init functionmanager! ");}} return null; }/** * Call a method with a parameter with a return value * @param funname */public <Result,Param> Result Invokewithall (String funname, C Lass<result> C,param Param) throws NullPointerException {if (Textutils.isempty (Funname)) {LOG.E (TAG, "Funn AME is null! ");} else {if (null! = Mfunctionwithparamwithresulthashmap) {functionwithparamwithresult<result,param> fu Nction = Mfunctionwithparamwithresulthashmap.get (funname); if (null! = function) {if (null! = c) {return c.cast (function.function (param)); }else {return function.function (param); }}else {log.e (TAG, "function is null!");}} else {throw new NullPointerException ("Mfunctionwithparamsonlyhashmap can not is null, please first init functionmanager!") ); }}reTurn null; }}
4 Write a method in activity
public void setfunctionforfragment (String tag) {if (Textutils.isempty (tag)) {LOG.E (MainActivity.class.getSimpleName ( ), "tag is null!"); Return } basefragment fragment = (basefragment) fm.findfragmentbytag (tag); Functionmanager Functionmanager = Functionmanager.getinstance (); Functionmanager.addfunction (New Functionnoparamnoresult (functionnoparamnoresult) {@Override public void function () {Toast.maketext (Mainactivity.this, "no parameter no return value", Toast.length_short). Show (); } }); Functionmanager.addfunction (New functionwithresultonly<string> (functionwithresultonly) {@Override public Str ing function () {return "no parameter has a return value"; } }); Functionmanager.addfunction (New functionwithparamonly<string> (functionwithparamonly) {@Override public void F Unction (String o) {toast.maketext (Mainactivity.this, O, Toast.length_short). Show (); } }); Functionmanager.addfunction (New Functionwithparamwithresult< String,string> (functionwithparamwithresult) {@Override public string function (String o) {return o; } }); Fragment.setfunctionmanager (Functionmanager);}
5 Edit a fragment base class (it is possible to integrate the class directly when the utility fragment), and bind the interface established above
public class Basefragment extends Fragment{public Functionmanager Mfunctionmanager; Private mainactivity mainactivity; public void Setfunctionmanager (Functionmanager mfunctionmanager) {this.mfunctionmanager = Mfunctionmanager; } @Override public void Onattach (context context) {Super.onattach (context); If (context instanceof mainactivity) {mainactivity = (mainactivity) context; Mainactivity.setfunctionforfragment (Gettag ()); } else {throw new RuntimeException (context.tostring () + "must implement Onfragmentinteractionlistener"); } } @Override public void Ondetach () {Super.ondetach (); mainactivity = null;} }
6 Inheritance Basefragment
public class Noparamnoresultfragment extends Basefragment {private Handler mhandler; Public noparamnoresultfragment (Handler Handler) {//Required empty public constructor this.mhandler = Handler; } @Override public void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); if (getarguments () = null) {}} @Override public View oncreateview (Layoutinflater inflater, ViewGroup Contai NER, Bundle savedinstancestate) {//Inflate the layout for this fragment view view = Inflater.inflate (R.layout.fragment_no_param_no_result, container, false); View.findviewbyid (R.id.txt_handle). Setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View v) {Message message = Mhandler.obtainmessage (); Message.what = 0x123; Message.obj = "Handle Communication"; Mhandler.sendmessage (message); } }); View.finDviewbyid (R.id.txt_noall). Setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View v) {Mfunctionmanager.invokenoall (Mainactivity.functionnoparamnoresult); } }); View.findviewbyid (R.id.txt_result). Setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View v) {//Mfunctionmanager.invokenoall (Mainactivity.functionnoparamnoresult); String result = Mfunctionmanager.invokewithresultonly (Mainactivity.functionwithresultonly,string.class); Toast.maketext (getactivity (), result, Toast.length_short). Show (); } }); View.findviewbyid (R.id.txt_param). Setonclicklistener (New View.onclicklistener () {@Override public void OnClick ( View v) {mfunctionmanager.invokewithparamonly (mainactivity.functionwithparamonly, "parameter no return value"); } }); View.findviewbyid (R.id.txt_withall). Setonclicklistener (New View.onclicklistener (){@Override public void OnClick (View v) {String result = Mfunctionmanager.invokewithall (mainact Ivity. Functionwithparamwithresult,string.class, "has a parameter return value"); Toast.maketext (getactivity (), result, Toast.length_short). Show (); } }); return view; }}
Description, the above when clicking on the control, will trigger the method added in the activity, so that the activity and fragment real-time communication, near and achieve the communication between fragment
Https://gitee.com/lzbgit/AppInterface
Architect's path to growth-an object-oriented universal interface based on Android fragment communication