Android:Activity與Fragment通信(99%)完美解決方案

前言


最近一直在想著能否有一種更好的方案來解決:Android中Activity與Fragment之間通信的問題吮蛹,什么叫更好呢浩淘,就是能讓Fragment的復(fù)用性高恩掷,性能還有好(不用反射)组哩,代碼還要好維護(hù)漫贞,不需要為每對Activity和Fragment之間定義接口而發(fā)愁。

先簡單說下Javascript這門語言吧闽坡,或許有人就會問:咱們不是聊Android的java問題嗎栽惶?怎么話題轉(zhuǎn)到JavaScript了。因?yàn)槲业慕鉀Q方案的啟發(fā)是從它來的疾嗅,沒興趣的朋友可以略過外厂。最近在學(xué)習(xí)javascript這門語言,同時自己搞Android(java)開發(fā)也有5年多時間了代承,所以在學(xué)習(xí)js的過程中汁蝶,就會慣性的把這兩者進(jìn)行比較。

與java語言的 嚴(yán)謹(jǐn) 相比 Javascript是一門"放蕩不羈"论悴、"不拘小節(jié)"(寬泛)的語言掖棉。
為什么要用"放蕩不羈"這個詞呢,下面是它的一個解釋:

放蕩不羈 [fàng dàng bù jī][解釋] 羈:約束膀估。放縱任性幔亥,不加檢點(diǎn),不受約束察纯。

因?yàn)槲矣X得這個詞更能充分的體現(xiàn)js弱類型的特點(diǎn)帕棉。
在給變量賦值時 可以這樣寫:

var a = 1; 

還可以這樣寫:

 var b = '123'; 
var o = new Object(); 

甚至還可以這樣寫:

var fun = new function(){};
 fun1 = new function(){}; 

可以把任何類型的值賦給一個變量,也可以不加var關(guān)鍵字來聲明一個變量饼记,是不是很任性香伴,很不拘束啊。

"不拘小節(jié)"主要體現(xiàn)了JavaScript的語法更寬泛具则、更簡單的特點(diǎn): 比如:

  js代碼:  
  //函數(shù)聲明不需要定義返回值即纲,參數(shù)前面不需要有類型出現(xiàn),
  //函數(shù)體里面就可以有返回值
  function max(a,b){ return a > b? a:b; } 
  /* *可以傳遞任意多個參數(shù)博肋,在java里面根本不可以 */ 
  function print(){ 
      var len = arguments.length; 
      for(var i = 0; i < len; i++){ 
          console.log(arguments[i]);
     } 
  } 

  相應(yīng)java代碼:
   int max(int a, int b){
       return a> b? a:b; 
  } 

  /* *傳遞任意多個Object類型的參數(shù) */ 
  void print(Object... args){
       for (int i = 0; i < args.length; i++){                 
              System.out.println(args[i]); 
        }
   } 

上面的代碼說明了JavaScript在聲明函數(shù)時低斋,不會有像java那么嚴(yán)格的規(guī)定,語法不拘小節(jié)束昵,語法更簡單(這里沒有說java不好的意思)拔稳。

啟發(fā)點(diǎn)

JavaScript中有一個重要的點(diǎn)(萬事萬物皆對象),函數(shù)也不列外锹雏,并且函數(shù)可以作為另外一個函數(shù)的參數(shù)巴比,如:

     js代碼: 
    //遍歷一個數(shù)組如果是它是數(shù)組,就把它乘以10再輸出 
     var array = [1,2, '你好' , '不' ,31,15];  
    //數(shù)組的each方法接收一個函數(shù) 
     testArray.each( function( value ){ 
           typeof value == 'number' ? alert( value *10 ):null;
    })  ;

當(dāng)我看到上面JavaScript中函數(shù)的用法時我眼前一亮礁遵,為啥我不可以借鑒之來解決android中activity與fragment通信的問題呢轻绞?


Fragment的使命


先讓我們聊聊Fragment為什么出現(xiàn),這對于我們解決Activity與Fragment的通信有幫助佣耐。一個新事物的產(chǎn)生總是為了解決舊事物存在的問題政勃,F(xiàn)ragment是android3.0的產(chǎn)物,在android3.0之前解決手機(jī)兼砖、平板電腦的適配問題是很頭疼的奸远,對ActivityGroup有印象的朋友既棺,應(yīng)該能深深的體會到ActivityGroup包裹的多個Activity之間切換等一系列的性能問題。由此Fragment誕生了懒叛。個人總結(jié)的Fragment的使命:

  • 解決手機(jī)丸冕、平板電腦等各種設(shè)備的適配問題
  • 解決多個Activity之間切換性能問題
  • 模塊化,因?yàn)槟K化導(dǎo)致復(fù)用的好處

Fragment的使用

Fragment是可以被包裹在多個不同Activity內(nèi)的薛窥,同時一個Activity內(nèi)可以包裹多個Fragment胖烛,Activity就如一個大的容器,它可以管理多個Fragment诅迷。所有Activity與Fragment之間存在依賴關(guān)系佩番。


Activity與Fragment通信方案

上文提到Activity與Fragment之間是存在依賴關(guān)系的,因此它們之間必然會涉及到通信問題罢杉,解決通信問題必然會涉及到對象之間的引用趟畏。因?yàn)镕ragment的出現(xiàn)有一個重要的使命就是:模塊化,從而提高復(fù)用性屑那。若達(dá)到此效果拱镐,F(xiàn)ragment必須做到高內(nèi)聚,低耦合持际。

現(xiàn)在大家動動腳趾都能想到的解決它們之間通信的方案有:handler沃琅,廣播,EvnetBus蜘欲,接口等(或許還有別的方案益眉,請大家多多分享),那我們就聊下這些方案姥份。

handler方案:

先上代碼

   public class MainActivity extends FragmentActivity{ 
      //聲明一個Handler 
      public Handler mHandler = new Handler(){       
          @Override
           public void handleMessage(Message msg) { 
                super.handleMessage(msg);
                 ...相應(yīng)的處理代碼
           }
     }
     ...相應(yīng)的處理代碼
   } 

    public class MainFragment extends Fragment{ 
          //保存Activity傳遞的handler
           private Handler mHandler;
           @Override
           public void onAttach(Activity activity) { 
                super.onAttach(activity);
               //這個地方已經(jīng)產(chǎn)生了耦合郭脂,若還有其他的activity,這個地方就得修改 
                if(activity instance MainActivity){ 
                      mHandler =  ((MainActivity)activity).mHandler; 
                }
           }
           ...相應(yīng)的處理代碼
     }

該方案存在的缺點(diǎn):

  • Fragment對具體的Activity存在耦合澈歉,不利于Fragment復(fù)用
  • 不利于維護(hù)展鸡,若想刪除相應(yīng)的Activity,F(xiàn)ragment也得改動
  • 沒法獲取Activity的返回數(shù)據(jù)
  • handler的使用個人感覺就很不爽(不知大家是否有同感)

廣播方案:

具體的代碼就不寫了埃难,說下該方案的缺點(diǎn):

  • 用廣播解決此問題有點(diǎn)大材小用了莹弊,個人感覺廣播的意圖是用在一對多,接收廣播者是未知的情況
  • 廣播性能肯定會差(不要和我說性能不是問題涡尘,對于手機(jī)來說性能是大問題)
  • 傳播數(shù)據(jù)有限制(必須得實(shí)現(xiàn)序列化接口才可以)
    暫時就想到這些缺點(diǎn)忍弛,其他的缺點(diǎn)請大家集思廣益下吧。

EventBus方案:

具體的EventBus的使用可以自己搜索下考抄,個人對該方案的看法:

  • EventBus是用反射機(jī)制實(shí)現(xiàn)的细疚,性能上會有問題(不要和我說性能不是問題,對于手機(jī)來說性能是大問題)
  • EventBus難于維護(hù)代碼
  • 沒法獲取Activity的返回數(shù)據(jù)

接口方案

我想這種方案是大家最易想到川梅,使用最多的一種方案吧疯兼,具體上代碼:

  //MainActivity實(shí)現(xiàn)MainFragment開放的接口 
  public class MainActivity extends FragmentActivity implements FragmentListener{ 
        @override
         public void toH5Page(){ }
       ...其他處理代碼省略
   } 

    public class MainFragment extends Fragment{

         public FragmentListener mListener;  
        //MainFragment開放的接口 
        public static interface FragmentListener{ 
            //跳到h5頁面
           void toH5Page();
         }

         @Override 
        public void onAttach(Activity activity) { 
              super.onAttach(activity); 
              //對傳遞進(jìn)來的Activity進(jìn)行接口轉(zhuǎn)換
               if(activity instance FragmentListener){
                   mListener = ((FragmentListener)activity); 
              }
         }
         ...其他處理代碼省略 
  } 

這種方案應(yīng)該是既能達(dá)到復(fù)用然遏,又能達(dá)到很好的可維護(hù)性,并且性能也是杠杠的镇防。但是唯一的一個遺憾是假如項(xiàng)目很大了啦鸣,Activity與Fragment的數(shù)量也會增加潮饱,這時候?yàn)槊繉ctivity與Fragment交互定義交互接口就是一個很頭疼的問題(包括為接口的命名来氧,新定義的接口相應(yīng)的Activity還得實(shí)現(xiàn),相應(yīng)的Fragment還得進(jìn)行強(qiáng)制轉(zhuǎn)換)香拉。 想看更好的解決方案請看下面章節(jié)啦扬。


大招來也

設(shè)計模式里經(jīng)常提到的一個概念就是封裝變化,同時受javascript中的函數(shù)的參數(shù)可以是函數(shù)對象的啟發(fā)下凫碌,我有了下面的想法扑毡,先上代碼:代碼地址

  /** * + Created by niuxiaowei on 2016/1/20.
  * 各種方法集合的類,可以把一個方法類以key-value的形式放入本類盛险,   
  * 可以通過key值來調(diào)用相應(yīng)的方法 */
   public class Functions { 

      //帶參數(shù)方法的集合瞄摊,key值為方法的名字 
      private  HashMap<String,FunctionWithParam> mFunctionWithParam ; 
      //無參數(shù)無返回值的方法集合,同理key值為方法名字
     private HashMap<String,FunctionNoParamAndResult> mFunctionNoParamAndResult ; 

      /** * 基礎(chǔ)方法類 */
     public static abstract class Function{
         //方法的名字苦掘,用來做調(diào)用换帜,也可以理解為方法的指針 
          public String mFunctionName; 
          public Function(String functionName){ 
                this.mFunctionName = functionName;
         } 
      } 

      /** * 帶有參數(shù)沒有返回值的方法
     * @param <Param> 參數(shù) */
     public static abstract class FunctionWithParam<Param> extends Function{ 

          public FunctionWithParam(String functionName) { 
              super(functionName);
         } 

        public abstract void function(Param param); 
    } 

    /** * 沒有參數(shù)和返回值的方法 */
   public static abstract class FunctionNoParamAndResult extends Function{ 
          public FunctionNoParamAndResult(String functionName) { 
                super(functionName); 
          } 

          public abstract void function(); 
    } 

    /** * 添加帶參數(shù)的函數(shù)
     * @param function {@link com.niu.myapp.myapp.view.util.Functions.FunctionWithParam} 
    * @return */
     public Functions addFunction(FunctionWithParam function){
             if(function == null){ 
                  return this;
             } 
            if(mFunctionWithParam == null){ 
                  mFunctionWithParam = new HashMap<>(1); 
            }   
         
        mFunctionWithParam.put(function.mFunctionName,function); 
        return this; 
      } 

      /** * 添加帶返回值的函數(shù) 
      * @param function {@link com.niu.myapp.myapp.view.util.Functions.FunctionWithResult}
     * @return */
     public Functions addFunction(FunctionNoParamAndResult function){ 
          if(function == null){ return this; } 
          if(mFunctionNoParamAndResult == null){ 
                mFunctionNoParamAndResult = new HashMap<>(1);
         } 
         mFunctionNoParamAndResult.put(function.mFunctionName,function); 
      return this; 
    }

     /** * 根據(jù)函數(shù)名,回調(diào)無參無返回值的函數(shù)
   * @param funcName */ 
    public void invokeFunc(String funcName) throws FunctionException {
         FunctionNoParamAndResult f = null; 
        if(mFunctionNoParamAndResult != null){ 
              f = mFunctionNoParamAndResult.get(funcName); 
              if(f != null){ f.function(); } 
        }
         if(f == null){ throw new FunctionException("沒有此函數(shù)"); }
     } 

    /** * 調(diào)用具有參數(shù)的函數(shù)
     * @param funcName 
    * @param param 
    * @param <Param> */ 
      public <Param> void invokeFunc(String funcName,Param param)throws FunctionException{ 
            FunctionWithParam f = null; 
            if(mFunctionWithParam != null){ 
                  f = mFunctionWithParam.get(funcName);
                   if(f != null){ f.function(param); } 
            }
     } 
}

設(shè)計思路:

1. 用一個類來模擬Javascript中的一個Function

Function就是此類鹤啡,它是一個基類惯驼,每個Functioon實(shí)例都有一個mFuncName 既然是方法(或者函數(shù))它就有有參數(shù)和無參數(shù)之分
FunctionWithParam<Param>是Function的子類,代表有參數(shù)的方法類递瑰,方法參數(shù)通過泛型解決
FunctionNoParamAndResult是Function的子類祟牲,代表無參無返回值的方法類

2. 一個可以存放多個方法(或者函數(shù))的類

Functions類就是此類,下面簡單介紹下Functions有4個主要方法:

  • addFunction(FunctionNoParamAndResult function) 添加一個無參無返回值的方法類
  • addFunction(FunctionWithParam function) 添加一個有參無返回值的方法類
  • invokeFunc(String funcName) 根據(jù)funcName調(diào)用一個方法
  • invokeFunc(String funcName,Param param) 根據(jù)funcName調(diào)用有參無返回值的方法類

使用舉例:代碼地址

每個app都有的基礎(chǔ)activity(BaseActivity)

     public abstract class BaseActivity extends FragmentActivity { 
          /** 
          * 為fragment設(shè)置functions,具體實(shí)現(xiàn)子類來做
         * @param fragmentId */ 
        public void setFunctionsForFragment(
              int fragmentId){
        }
   } 

其中的一個activity:

     public class MainActivity extends BaseActivity { 

          @Override public void setFunctionsForFragment(int fragmentId) {
               super.setFunctionsForFragment(fragmentId); 
               switch (fragmentId) {
                   case R.id.fragment_main:
                     FragmentManager fm = getSupportFragmentManager(); 
                    BaseFragment fragment = (BaseFragment) fm.findFragmentById(fragmentId);
                   //開始添加functions
               fragment.setFunctions(new Functions()
                   .addFunction(new Functions.FunctionNoParamAndResult(MainFragment.FUNCTION_NO_PARAM_NO_RESULT) {

                       @Override 
                      public void function() {
                           Toast.makeText(MainActivity.this, "成功調(diào)用無參無返回值方法", Toast.LENGTH_LONG).show(); 
                      }
               }).
                  addFunction(new Functions.FunctionWithParam<Integer>(MainFragment.FUNCTION_HAS_PARAM_NO_RESULT) { 
                        @Override 
                        public void function(Integer o) { 
                            Toast.makeText(MainActivity.this, "成功調(diào)用有參無返回值方法 參數(shù)值=" + o, Toast.LENGTH_LONG).show(); } }));
                       }
               }
 }

每個app都會有的基礎(chǔ)fragment(BaseFragment)

     public abstract class BaseFragment extends Fragment { 
            protected BaseActivity mBaseActivity; 
            /** * 函數(shù)的集合 */ 
            protected Functions mFunctions; 

            /** * activity調(diào)用此方法進(jìn)行設(shè)置Functions
           * @param functions */
           public void setFunctions(Functions functions){ 
                this.mFunctions = functions;
           } 

          @Override 
          public void onAttach(Activity activity) { 
                super.onAttach(activity);
               //呼叫activity進(jìn)行回調(diào)方法的設(shè)置 
              if(activity instanceof BaseActivity){ 
                    mBaseActivity = (BaseActivity)activity;
                     mBaseActivity.setFunctionsForFragment(getId());
               } 
          } 
  } 

MainActivity對應(yīng)的MainFragment

    public class MainFragment extends BaseFragment {

           /** * 沒有參數(shù)沒有返回值的函數(shù) */ 
          public static final String FUNCTION_NO_PARAM_NO_RESULT = "FUNCTION_NO_PARAM_NO_RESULT"; 
          /** * 有參數(shù)沒有返回值的函數(shù) */
         public static final String FUNCTION_HAS_PARAM_NO_RESULT = "FUNCTION_HAS_PARAM_NO_RESULT"; 

          @Override
           public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
               super.onViewCreated(view, savedInstanceState);
               mBut1 = (Button) getView().findViewById(R.id.click1); 
                mBut3 = (Button) getView().findViewById(R.id.click3);

               mBut1.setOnClickListener(new View.OnClickListener() { 
                    @Override
                     public void onClick(View v) { 
                          try {
                               //調(diào)用無參無返回值的方法 
                               mFunctions.invokeFunc(
                                FUNCTION_NO_PARAM_NO_RESULT);       
                        } catch (FunctionException e) {
                               e.printStackTrace(); 
                        } 

                    } 
              }); 

              mBut3.setOnClickListener(new View.OnClickListener() { 
                  @Override
                   public void onClick(View v) {
                         try { 
                                //調(diào)用有參無返回值的方法 
                                mFunctions.invokeFunc(
                                 FUNCTION_HAS_PARAM_NO_RESULT, 100); 
                        } catch (FunctionException e) {
                               e.printStackTrace(); }
                     }
               }); 
  } 

看到這您是不是覺得已經(jīng)結(jié)束了抖部,當(dāng)然是沒有了说贝,因?yàn)檫€有2個問題沒解決。方法返回值和方法接收多個參數(shù)的問題慎颗。

方法返回值的問題

上代碼:代碼地址

    /** * 有返回值乡恕,沒有參數(shù)的方法
     * @param <Result> */ 
    public static abstract class FunctionWithResult<Result> extends Function{

         public FunctionWithResult(String functionName) { 
              super(functionName);
         } 

          public abstract Result function(); 
    } 

    /** * 帶有參數(shù)和返回值的 方法 
    * @param <Result> 
    * @param <Param> */
   public static abstract class FunctionWithParamAndResult<Result,Param> extends Function{ 
        public FunctionWithParamAndResult(String functionName) { 
              super(functionName); 
        } 

        public abstract Result function(Param data);
 } 

FunctionWithResult<Result>無參數(shù)有返回值的方法類
FunctionWithParamAndResult<Result,Param> 有參數(shù)也有返回值的方法類
在Functions類中定義添加和調(diào)用這2種方法類的 相應(yīng)方法。

其次是方法含有多個參數(shù)的問題

在解決此問題時我想了很多辦法(比如怎樣引入多個泛型哗总,但最終以失敗告終几颜,希望有看了這篇文章的朋友可以多提下寶貴意見)。然后我就想到了用Bundle來解決多參數(shù)的問題讯屈,把多個參數(shù)放到Bundle中蛋哭,但是在往Bundle中塞入數(shù)據(jù)時得有一個對應(yīng)的key值,生成key值以及記住key值(記住key值是為了從Bundle中取數(shù)據(jù))是一個繁瑣的事涮母。同時Bundle不能傳遞非序列化對象谆趾。所以就封裝了一個FunctionParams類解決以上問題躁愿,請看類的實(shí)現(xiàn): 代碼地址

  /** * 函數(shù)的參數(shù),當(dāng)函數(shù)的參數(shù)涉及到多個值時沪蓬,可以用此類彤钟,
   * 此類使用規(guī)則:存參數(shù)與取參數(shù)的順序必須一致,
   * 比如存參數(shù)順序是new 
 *FunctionParamsBuilder().putString("a").putString("b").putInt(100); 
    *取的順序也是: functionParams.getString(),   
    *functionParams.getString(), functionParams.getInt(); */
 public static class FunctionParams { 

      private Bundle mParams = new Bundle(1); 
      private int mIndex = -1; 
      private Map mObjectParams = new HashMap(1); 

      FunctionParams(Bundle mParams,Map mObjectParams){ 
          this.mParams = mParams; 
          this.mObjectParams = mObjectParams;
     } 

    public <Param> Param getObject(Class<Param> p){ 
        if(mObjectParams == null){ return null; } 
        return p.cast(mObjectParams.get((mIndex++) + "")); } 

    /** * 獲取int值 
    * @return */ 
    public int getInt(){
         if(mParams != null){ 
              return mParams.getInt((mIndex++) + ""); } return 0; 
    } 

    /** * 獲取int值 
    * @param defalut 
    * @return */ 
    public int getInt(int defalut){ 
        if(mParams != null){ 
          return mParams.getInt((mIndex++) + ""); 
        }
       return defalut;
     } 

    /** * 獲取字符串 
    * @param defalut * @return */
     public String getString(String defalut){ 
        if(mParams != null){ 
          return mParams.getString((mIndex++) + ""); 
        } 
        return defalut; 
    } 

    /** * 獲取字符串 * @return */ 
    public String getString(){ 
        if(mParams != null){
             return mParams.getString((mIndex++) + ""); 
      } return null; 
    } 

      /** * 獲取Boolean值 
    * @return 默認(rèn)返回false */
     public boolean getBoolean(){ 
        if(mParams != null){ 
            return mParams.getBoolean((mIndex++) + ""); 
        } return false;
     }

     /** * 該類用來創(chuàng)建函數(shù)參數(shù) */
     public static class FunctionParamsBuilder{

         private Bundle mParams ;
         private int mIndex = -1;
         private Map mObjectParams = new HashMap(1); 

        public FunctionParamsBuilder(){ } 

        public FunctionParamsBuilder putInt(int value){
             if(mParams == null){ 
                  mParams = new Bundle(2);
             } 
              mParams.putInt((mIndex++) + "", value); 
              return this; 
      } 

      public FunctionParamsBuilder putString(String value){ 
            if(mParams == null){ 
                mParams = new Bundle(2);
           } 
            mParams.putString((mIndex++) + "", value); 
            return this; 
    }

     public FunctionParamsBuilder putBoolean(boolean value){ 
          if(mParams == null){ mParams = new Bundle(2); } 
          mParams.putBoolean((mIndex++) + "", value); 
          return this;
     } 

      public FunctionParamsBuilder putObject(Object value){ 
          if(mObjectParams == null){ 
              mObjectParams = new HashMap(1); 
          } 
          mObjectParams.put((mIndex++) + "", value);
           return this;
     }

     public FunctionParams create(){
         FunctionParams instance = new FunctionParams(mParams,mObjectParams); return instance; 
    }
  } 
}

FunctionParams封裝了取參數(shù)的功能跷叉,比如:

   public <Param> Param getObject(Class<Param> p){ 
        if(mObjectParams == null){ return null; }
         return p.cast(mObjectParams.get((mIndex++) + ""));
   }

取對象參數(shù)的功能逸雹,不需要傳人key值,只需要傳人需要即將取出來的類的Class實(shí)例即可

FunctionParamsBuilder類云挟,看它的名字就知道是用了設(shè)計模式里的Builder(構(gòu)建)模式梆砸。該類是用來存放參數(shù)的,當(dāng)所有的參數(shù)都存放完畢后調(diào)用create()方法創(chuàng)建一個FunctionParams對象事物都是有兩面性的园欣,有缺點(diǎn)就有優(yōu)點(diǎn)帖世,只不過是在某些場合下優(yōu)點(diǎn)大于缺點(diǎn),還是反之沸枯。
FunctionParams解決了以上提到的Bundle傳遞多參數(shù)種種不便的問題日矫,但同時FunctionParams也有一個缺點(diǎn)就是存參數(shù)的順序與取參數(shù)的順序一定要一致,比如:

    //存的順序 new       
    FunctionParamsBuilder().putString("1").putInt(2)
    .putBoolean(true).create(); 

    //取的順序 
    functionParams.getString(); 
    functionParams.getInt(); 
    functionParams.getBoolean();

但是這種缺點(diǎn)函數(shù)的定義來看也不是缺點(diǎn)绑榴。

Activity與Fragment之間的通信是通過Functions的哪轿,即把變化的部分封裝在Functions是類中,F(xiàn)unctions起一個橋梁作用彭沼。

此方案優(yōu)點(diǎn):

  • Fragment與Activity的耦合性幾乎沒有
  • 性能也好(沒用反射)
  • 可以從Activity獲取返回數(shù)據(jù)
  • 擴(kuò)展性好(新增加的成對的Activity與Fragment之間的通信只需做以下幾步:
    1.新增加Activity只需要覆蓋BaseActivity中的 setFunctionsForFragment(int fragmentId) 方法缔逛,把相應(yīng)的回調(diào)函數(shù)加入。
    2.相應(yīng)的Fragment定義函數(shù)key值即可)

總結(jié)

簡單總結(jié)為以下幾點(diǎn):

  • Fragment的使命
  • Activity與Fragment之間通信的解決方案(handler姓惑,廣播褐奴,EventBus,接口)的優(yōu)缺點(diǎn)于毙。
  • 我自己關(guān)于Activity與Fragment之間通信的解決方案(Functions)敦冬,其實(shí)解決的主要是Fragment調(diào)用Activity的方案。

希望大家能多提寶貴意見唯沮,多交流脖旱。代碼地址

本人微信:704451290

本人公眾賬號
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市介蛉,隨后出現(xiàn)的幾起案子萌庆,更是在濱河造成了極大的恐慌,老刑警劉巖币旧,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件践险,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)巍虫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門彭则,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人占遥,你說我怎么就攤上這事俯抖。” “怎么了瓦胎?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵芬萍,是天一觀的道長。 經(jīng)常有香客問我凛捏,道長担忧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任坯癣,我火速辦了婚禮,結(jié)果婚禮上最欠,老公的妹妹穿的比我還像新娘示罗。我一直安慰自己,他們只是感情好芝硬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布蚜点。 她就那樣靜靜地躺著,像睡著了一般拌阴。 火紅的嫁衣襯著肌膚如雪绍绘。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天迟赃,我揣著相機(jī)與錄音陪拘,去河邊找鬼。 笑死纤壁,一個胖子當(dāng)著我的面吹牛左刽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播酌媒,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼欠痴,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了秒咨?” 一聲冷哼從身側(cè)響起喇辽,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎雨席,沒想到半個月后菩咨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年旦委,在試婚紗的時候發(fā)現(xiàn)自己被綠了奇徒。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡缨硝,死狀恐怖摩钙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情查辩,我是刑警寧澤胖笛,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站宜岛,受9級特大地震影響长踊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜萍倡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一身弊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧列敲,春花似錦阱佛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至所意,卻和暖如春淮逊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背扶踊。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工泄鹏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人姻檀。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓命满,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绣版。 傳聞我的和親對象是個殘疾皇子胶台,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容