Activity 与 Fragment 之间常见的几种通信方式?

最近在和小伙伴一起维护一个github项目,https://github.com/Moosphan/Android-Daily-Interview。
每天出一道面试题。感兴趣的可以点进去看看。最近要开始整理答案。所以顺手也在这里发布下自己写的相关面试题的答案。

原题链接
以下是正文。

开始介绍方法之前,先借用之前lx36301766 写的答案里的一句话,我个人觉得写的很到位:

说到底就是两个普通的JAVA对象相互都持有对方的引用,直接回调就成,哪还需要什么别的通信方式,很简单的问题别搞复杂了

大家都知道java是面向对象的编程语言。只要拿到对象,想做什么操作其实很简单。好开始正文。

从两个方面开始说

  • Activity与Fragment通信
  • Fragemnt与Activity通信

1 Activity与Fragment通信

1.1 广播

这个就不写,相信大家都会

1.2 对象调用public方法

public class TestActivity extends AppCompatActivity{
    
    private TestFragmet testFragment;
    
    public void test(){
        testFragment = new TestFragmet();
        testFragment.doTest();
    }
}
public class TestFragmet extends Fragmenyt{
    private TestActivity activity;
    
    public void doTest(){
        Log.d(TAG,"收到消息");
    }
}

1.3 接口

    public class TestActivity extends Activity{

        private ITest iTest;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            iTest = new TestFragment();
            iTest.doTest();
        }
    }

    public class TestFragment extends Fragment implements ITest{

        @Override
        public void doTest() {
            Log.i(TAG, "doTest: ");
        }
    }

    public interface ITest{
        void doTest();
    }

1.4 观察者

这里模拟一个场景,用户在activity里登录状态发生了改变,fragment展示退出登录的UI。我真实项目里也是采用的观察者模式管理登录状态,因为登录状态的改变牵连到一系列的改变。

    public class TestActivity extends Activity {

        final int LOGIN_OUT = 0;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            LoginManager.loginStatusChanged(LOGIN_OUT);
        }
    }


    public class TestFragment extends Fragment implements LoginObserver {
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

            /**
             * 订阅事件
             */
            LoginManager.registerLoginObserver(this);
            return super.onCreateView(inflater, container, savedInstanceState);
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            /**
             * 反订阅事件
             */
            LoginManager.unregisterLoginObserver(this);
        }

        @Override
        public void loginStatusChange(int status) {
            Log.i(TAG, "loginStatusChange: "+status);
        }
    }


    public class LoginManager {

        private static ArrayList<LoginObserver> loginObserverList = new ArrayList<>();

        public static void registerLoginObserver(LoginObserver loginObserver){
            loginObserverList.add(loginObserver);
        }

        public static void unregisterLoginObserver(LoginObserver loginObserver){
            loginObserverList.remove(loginObserver);
        }

        public static void loginStatusChanged(int loginstatus){
            for (LoginObserver observer:loginObserverList){
                if (observer!=null){
                    observer.loginStatusChange(loginstatus);
                }
            }
        }
    }

    public interface LoginObserver{

        void loginStatusChange(int status);
    }

1.5 eventbus

也没什么好说的,相信大家都用过

2 Fragemnt与Activity通信

2.1 广播

同1.1

2.2 对象调用public方法

    public class TestActivity extends Activity {
        
        public void doTest(){
            Log.i(TAG, "doTest: ");
        }
    }
    public class TestFragment extends Fragment {

        private TestActivity activity;
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            if (getActivity() instanceof TestActivity){
                activity = getActivity();
            }
        }

        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            return super.onCreateView(inflater, container, savedInstanceState);
        }

        void test(){
            activity.doTest();
        }
    }

2.3 接口

    public class TestActivity extends Activity implements ITest{
        
        @Override
        public void doTest() {
            Log.i(TAG, "doTest: ");
        }
    }
    public class TestFragment extends Fragment {

        private ITest iTest;
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            if (context instanceof ITest){
                iTest = (ITest) context;
            }
        }

        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            return super.onCreateView(inflater, container, savedInstanceState);
        }

        void test(){
            iTest.doTest();
        }
    }


    public interface ITest{
        void doTest();
    }

2.4 观察者

同1.4,只不过这次是fragmnet改变用户登录状态,activiy观察事件而已。

    public class TestActivity extends Activity implements LoginObserver {



        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            LoginManager.registerLoginObserver(this);
        }

        @Override
        protected void onDestroy() {
            super.onDestroy();
            LoginManager.unregisterLoginObserver(this);
        }

        @Override
        public void loginStatusChange(int status) {

        }
    }
    public class TestFragment extends Fragment {

        final int LOGIN_OUT = 0;

        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            return super.onCreateView(inflater, container, savedInstanceState);
        }


        void doTest(){
            LoginManager.loginStatusChanged(LOGIN_OUT);
        }
    }
    public class LoginManager {

        private static ArrayList<LoginObserver> loginObserverList = new ArrayList<>();

        public static void registerLoginObserver(LoginObserver loginObserver){
            loginObserverList.add(loginObserver);
        }

        public static void unregisterLoginObserver(LoginObserver loginObserver){
            loginObserverList.remove(loginObserver);
        }

        public static void loginStatusChanged(int loginstatus){
            for (LoginObserver observer:loginObserverList){
                if (observer!=null){
                    observer.loginStatusChange(loginstatus);
                }
            }
        }
    }
    public interface LoginObserver{

        void loginStatusChange(int status);
    }

2.5 eventbus

自行百度吧,这个很简单。

题外话

大家可能发现接口和对象调用public方法出奇的相似,那么为什么要多次一举写个接口呢?大家可以点击一下TestFragment#test() 里的iTest.doTest();会发现跳转到了ITest接口里,而点击TestFragment#test()里的activity.doTest();确实跳转到了TestActivity里。到这里相信大家就看出接口的一个妙用,隐藏实现,当然不是完全隐藏,你可以通过搜索哪里实现继续查看。当然接口还有其他功能,就不赘述了。

你可能感兴趣的:(Android)