架構師成長之路-基於android fragment通訊的物件導向的萬能介面

來源:互聯網
上載者:User

標籤:冗餘   資料   cto   不能   end   接收   sha   group   desc   

前言

  開發一個app時,常用Activity和Fragment,由於操作方便Fragment越來越受歡迎,這樣就避免不了Activity和Fragment、Fragment和Fragment之間的通訊,我們知道Fragment和Fragment之間不能直接進行通訊的,而是通過Activity進行通訊。那麼Activity和Fragment有幾種通訊方式呢,它們的優缺點又是什嗎?一 常用的Activity和Fragment幾種通訊方式1 通過Handle在Activity建立一個Handle機制執行個體,然後在建立Fragment的通過構造方法把Handle執行個體傳遞過去,這樣Fragment就可以往Activity傳送資料了。但這樣如下缺點:(1)Activity和Fragment之間耦合性增大;(2)Activity處理後的結果不能即時反饋給Fragment;(3)提高了記憶體流失風險;2 使用static變數缺點很明確增大記憶體消耗;3 使用廣播分別在Activity和Fragment中註冊廣播,這樣就可以實現通訊了。其缺點:(1)效能差,有延遲,使用者體驗就會差;(2)一般使用的是標準廣播,一個發送,多個接收者,大材小用,效能差;(3)代碼冗餘;(4)傳播的資料有限;4 EventBus 、rxBus(俗稱萬能油)其使用方法參考官方文檔,其優點就是實用起來簡單方便,其缺點也很明顯:(1)EventBus 、rxBus其內部使用的是反射機制,那麼其效能就會降低;(2)代碼維護困難(不熟悉的項目代碼的新人很難找到實現的方法在是如何調用的);(3)資料返回困難,它們是單向傳遞;5 普通介面在Fragment寫一個介面,讓Activity去實現這個介面,通過這個介面把Activity與Fragment綁定在一起,這樣Activity和Fragment即時進行通訊了,其實Google推薦就是這麼乾的,由於每個Fragment都寫一個介面,就會造成代碼冗餘;如果Fragment少的話還好,多的話,Activity實現多個介面,顯得Activity頭部很大,況且介面的命名也是一個問題;二 萬能介面如果在5的基礎能夠解決代碼冗餘、介面命名就好了,我們知道一個函數包括函數名、函數體、參數、傳回值,那麼就可以通過搭建一個簡單的架構實現上述問題。1 建立基類
public abstract  class Function {    /** 方法名 */    public String mFunctionName ;    public Function (String funName){        this.mFunctionName = funName;    }}

2 建立無(有)參數無(有)四類

/** *  無參無傳回值 * <h3>Description</h3> * TODO * <h3>Author</h3> luzhenbang * <h3>Date</h3> 2018/1/4 16:13 * <h3>Copyright</h3> Copyright (c)2018 Shenzhen TL  Co., Ltd. Inc. All rights reserved. */public abstract class FunctionNoParamNoResult extends Function {    public FunctionNoParamNoResult(String funName) {        super(funName);    }    public abstract void function();}

 

/** *  有參無傳回值 * <h3>Description</h3> * TODO * <h3>Author</h3> luzhenbang * <h3>Date</h3> 2018/1/4 16:13 * <h3>Copyright</h3> Copyright (c)2018 Shenzhen TL  Co., Ltd. Inc. All rights reserved. */public abstract class FunctionWithParamOnly<Param> extends Function {    public FunctionWithParamOnly(String funName) {        super(funName);    }    public abstract void function(Param param);}    

 

/** *  有參有傳回值 * <h3>Description</h3> * TODO * <h3>Author</h3> luzhenbang * <h3>Date</h3> 2018/1/4 16:13 * <h3>Copyright</h3> Copyright (c)2018 Shenzhen TL  Co., Ltd. Inc. All rights reserved. */public abstract class FunctionWithParamWithResult<Result,Param> extends Function {    public FunctionWithParamWithResult(String funName) {        super(funName);    }    public abstract Result function(Param param);}

 

/** *  無參有傳回值 * <h3>Description</h3> * TODO * <h3>Author</h3> luzhenbang * <h3>Date</h3> 2018/1/4 16:13 * <h3>Copyright</h3> Copyright (c)2018 Shenzhen TL  Co., Ltd. Inc. All rights reserved. */public abstract class FunctionWithResultOnly<Result> extends Function {    public FunctionWithResultOnly(String funName) {        super(funName);    }    public abstract Result function();}

  

3 建立管理器類

public class FunctionManager {private static FunctionManager instance = null;    public static final String TAG = FunctionManager.class.getSimpleName() + "-------->";    /**容器,用來儲存方法名字 key 對應的方法名 value 對應的是 參數返回對象*/    private HashMap<String,FunctionWithParamWithResult> mFunctionWithParamWithResultHashMap = 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;    }/**     * 添加無參無傳回值的方法     * @return     */    public FunctionManager addFunction(FunctionNoParamNoResult function){mFunctionNoParamNoResultHashMap.put(function.mFunctionName,function);        return this;    }/**     * 添加有傳回值的方法     * @return     */    public FunctionManager addFunction(FunctionWithResultOnly function){mFunctionWithResultOnlyHashMap.put(function.mFunctionName,function);        return this;    }/**     * 添加有參數的方法     * @return     */    public FunctionManager addFunction(FunctionWithParamOnly function){mFunctionWithParamsOnlyHashMap.put(function.mFunctionName,function);        return this;    }/**     * 添加有參有傳回值的方法     * @return     */    public FunctionManager addFunction(FunctionWithParamWithResult function){mFunctionWithParamWithResultHashMap.put(function.mFunctionName,function);        return this;    }/**     * 調用無傳回值無參數的方法     * @param funName     */    public void invokeNoAll (String funName) throws NullPointerException {if (TextUtils.isEmpty(funName)){            Log.e(TAG,"funName is null !");        }else {if ( null != mFunctionNoParamNoResultHashMap){                FunctionNoParamNoResult function =  mFunctionNoParamNoResultHashMap.get(funName);                if (null != function){                    function.function();                }else {                    Log.e(TAG,"function is null !");                }            }else {throw new NullPointerException("mFunctionNoParamNoResultHashMap can not be null ,please first init FunctionManager !");            }        }    }/**     * 調用有參數的方法     * @param funName     */   public <Param> void invokeWithParamOnly (String funName,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 be null ,please first init FunctionManager !");            }        }    }/**     * 調用有傳回值的方法     * @param funName     */   public <Result> Result invokeWithResultOnly (String funName, Class<Result> c) throws NullPointerException {if (TextUtils.isEmpty(funName)){            Log.e(TAG,"funName is null !");        }else {if ( null != mFunctionWithResultOnlyHashMap){                FunctionWithResultOnly function =  mFunctionWithResultOnlyHashMap.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 be null ,please first init FunctionManager !");            }        }return null;   }/**     * 調用有參數有傳回值的方法     * @param funName     */    public <Result,Param> Result invokeWithAll (String funName, Class<Result> c,Param param) throws NullPointerException {if (TextUtils.isEmpty(funName)){            Log.e(TAG,"funName is null !");        }else {if ( null != mFunctionWithParamWithResultHashMap){                FunctionWithParamWithResult<Result,Param> function =  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 be null ,please first init FunctionManager !");            }        }return null;    }}

4 在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, "無參無傳回值", Toast.LENGTH_SHORT).show();        }    });    functionManager.addFunction(new FunctionWithResultOnly<String>(FunctionWithResultOnly) {@Override        public String function() {return "無參有傳回值";        }    });    functionManager.addFunction(new FunctionWithParamOnly<String>(FunctionWithParamOnly) {@Override        public void function(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 編輯一個Fragment基類(實用Fragment的時候直接整合該類就可以了),並綁定上面建立的介面

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 繼承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 container,                             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 通訊";                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,"有參無傳回值");            }        });        view.findViewById(R.id.txt_withAll).setOnClickListener(new View.OnClickListener() {@Override            public void onClick(View v) {                String result =  mFunctionManager.invokeWithAll(MainActivity.FunctionWithParamWithResult,String.class,"有參有傳回值");                Toast.makeText(getActivity(), result, Toast.LENGTH_SHORT).show();            }        });        return view;    }}

說明,上述在點擊控制項的時候,會觸發在Activity添加的方法,這樣就可以實現Activity與Fragment即時通訊,近而實現Fragment之間的通訊  

https://gitee.com/lzbgit/AppInterface  

 

架構師成長之路-基於android fragment通訊的物件導向的萬能介面

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.