Fragment和Activity之間通訊萬能接口

android自從Fragment出來之後就備受關注,可是Fragment是依賴Activity而存在,那麼二者之間的交互式必不可少的,那麼他們之間須要進行通訊和數據交互,目前經常使用的方式有:android

一、EventBus框架

二、靜態變量ide

三、廣播this

四、接口方式繼承

五、Handler接口

目前大體就這5種交互方式,除了接口外,其它三種都是單向的數據傳遞。而通常的接口方式咱們也是不一樣的Fragment就會有不一樣的接口,這樣Activity須要實現的接口就很是多,那麼可否有統一的接口來實現這個功能,而且可以相互傳遞數據。咱們看下面萬能接口的定義get

咱們分析接口的特色:方法名,參數和返回值(這二者可能有也可能沒有),所以it

首先,咱們定義一個抽象類,名爲FunctionInterfaceio

public abstract class FunctionInterface{

    public String functionName;

    public FunctionInterface(String functionName) {
        this.functionName = functionName;
    }
}

這個類很簡單,就是一個方法名稱而已,下面繼承類須要按照參數和返回值的有無來定義ast

public abstract class FunctionNoParamNoResult extends FunctionInterface{

    public FunctionNoParamNoResult(String name) {
        super(name);
    }

    public abstract void function();
}

上面這個類申明的是沒有參數也沒有返回值的接口,有一個抽象方法function,它是咱們須要回調實現具體邏輯的,另外還有有返回值沒有參數的接口,有參數沒有返回值和有參數有返回值的接口申明,下面貼一個有返回值的接口,其它的不貼了

public abstract class FunctionWithParamOnly<Param> extends FunctionInterface{

    public FunctionWithParamOnly(String name) {
        super(name);
    }

    public abstract void function(Param data);
}

接口申明完成後,咱們須要一個管理的類來保存接口,FunctionManager

由於全部的接口都保存在這個管理類中,因此咱們要將這個類定義爲單例模式

private static final FunctionManager ourInstance = new FunctionManager();

public static FunctionManager getInstance() {
    return ourInstance;
}

private HashMap<String, FunctionNoParamNoResult> mFunctionNoParamNoResult;
private HashMap<String, FunctionWithParamOnly> mFunctionWithParamOnly;

既然是管理接口的類,那麼接口的添加和接口的調用都在這裏實現,下面是其中一個接口類型的實現

public FunctionManager addFunction(FunctionNoParamNoResult function) {
    mFunctionNoParamNoResult.put(function.functionName, function);
    return this;
}

public void invokeFunction(String name) {
    if (TextUtils.isEmpty(name)) {
        return;
    }
    if (null != mFunctionNoParamNoResult) {
        FunctionNoParamNoResult f = mFunctionNoParamNoResult.get(name);
        if (null != f) {
            f.function();
        } else {
            try {
                throw new FunctionException("Has no function exception: " + name);
            } catch (FunctionException e) {
                e.printStackTrace();
            }
        }
    }
}

到目前爲止,接口的申明和接口的管理已經作完,剩下的是接口的實現和被調用方式,在Fragment中,咱們要先獲取到管理接口類的實例,而後才能調用invokeFunction方法,那麼在初始化時就要將實例注入到Fragment中,

protected FunctionManager mFunctionManager;
protected MainActivity mActivity;

public void setmFunctionManager(FunctionManager manager) {
    this.mFunctionManager = manager;
}

注入完成後,就能夠直接使用FunctionManager的方法來調用對應接口的方法,

public class Fragment1 extends BaseFragment {

    public static final String FUCTIOIN_NAME = Fragment1.class.getName() + "NPNR";

    private Button btn;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment, container, false);
        btn = (Button) view.findViewById(R.id.button);
        btn.setText("First");
        btn.setOnClickListener(clickListener);
        Button test = (Button) view.findViewById(R.id.test_button);
        test.setOnClickListener(testListener);
        return view;
    }

    private View.OnClickListener clickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mFunctionManager.invokeFunction(FUCTIOIN_NAME);
        }
    };

這裏調用很方便,只有一行代碼便可實現,若是要調用帶參數的方法呢,

private View.OnClickListener testListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        OperateModel model = new OperateModel();
        model.num1 = 100;
        model.num2 = 12;
        Float result = mFunctionManager.invokeFunction(FUCTIOIN_NAME, model, Float.class);
        Toast.makeText(mActivity, model.num1 + "*" + model.num2 + "=" + result, Toast.LENGTH_SHORT).show();
    }
};

其實也就一行代碼實現了。

那麼剩下的工做就是Activity如何來處理這個接口和接口的實現了。在Activity初始化的時候,咱們就須要將FunctionManager的實例注入到Fragment中,而後針對不一樣Fragment邏輯實現接口的邏輯,具體以下

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    init();
}

public void inject(String tag) {
Fragment fragment = fragmentTransaction.findFragmentByTag(tag);
fragment.setmFunctionManager(FunctionManager.getInstance().addFunction(new FunctionNoParamNoResult(Fragment1.FUCTIOIN_NAME) {
    @Override
    public void function() {
        Toast.makeText(MainActivity.this, "Invoke No Param No Result function successfully", Toast.LENGTH_SHORT).show();
    }
}).addFunction(new FunctionWithParamAndResult<OperateModel, Float>(Fragment1.FUCTIOIN_NAME) {
    @Override
    public Float function(OperateModel data) {
        if (null != data) {
            return Float.valueOf(data.num1 * data.num2);
        }
        return 0.0f;
    }
}));
}

到這裏,通用的接口框架已經完成,不一樣的Fragment能夠根據須要調用不一樣類型的接口實現,在Activity中不須要去實現各類各樣的接口實現,只用動態addFunction就能處理有參無參,有返回值無返回值的全部類型。

相關文章
相關標籤/搜索