【发布时间】:2019-12-13 06:41:28
【问题描述】:
Android 开发者大家好,
我想知道你们如何将复杂的不可序列化(和不可打包)对象传递给片段。 (比如Listener、Api客户端……)
让我解释一下我的用例:
用例
我正在构建一个由一个“主机”活动和 3 个片段组成的 Android 应用程序。 目前我正在使用片段上的自定义构造函数传递对象(我知道这是不好的做法)。
片段构造函数如下所示:
/**
* Do not remove ever or you'll face RuntimeException
*/
public FirstFragment() {
}
public FirstFragment(Session session,
ApiClient apiClient,
FirebaseAnalytics firebaseAnalytics) {
mSession = session;
mApiClient = apiClient;
mFirebaseAnalytics = firebaseAnalytics;
}
我在这样的主机活动中使用它们
private FirstFragment getFirstFragment() {
if (mFirstFragment == null) {
mFirstFragment = new FirstFragment(mSession, mApiClient, mFirebaseAnalytics);
}
return mHomeFragment;
}
[...]
private void loadFragment(Fragment fragment, String tag) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, fragment, tag);
transaction.commit();
}
[...]
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case FIRST_FRAGMENT_RES_ID:
toolbar.setTitle(R.string.first_fragment_title);
loadFragment(getFirstFragment(), "first_fragment");
return true;
[...]
}
return false;
}
};
这个解决方案几乎一直都运行良好。但有时(我不知道确切的时间)会调用默认构造函数,因此所有本地成员都是空的。
可能的解决方案
为了解决这个问题,我正在考虑以下解决方案:
单身人士,到处都是单身人士
我传递的大多数对象都是单例,因此我可以在片段的默认构造函数中访问它们:
public FirstFragment() {
mSession = Session.getInstance(getContext());
mApiClient = ApiClient.getInstance(getContext());
mFirebaseAnalytics = FirebaseAnalytics.getInstance(getContext());
}
问题
但是,如果我需要传递回调或其他东西,上述解决方案将不起作用。那怎么能这样呢?
使用父活动访问对象
我认为这是最丑陋的解决方案之一,因为它会将 Fragments 耦合到父 Activity。这个想法是这样的
public FirstFragment() {
mSession = Session.getInstance(getContext());
mApiClient = ApiClient.getInstance(getContext());
mFirebaseAnalytics = FirebaseAnalytics.getInstance(getContext());
mListener = (Listener) getActivity(); // <- will works because parent activity implement the interface
}
使用广播和接收器
我们的想法是在任何地方都传递单例,并使用广播和接收器而不是侦听器。
你们是如何处理这种情况的?
提前致谢!
【问题讨论】:
-
不要在构造函数中传递,而是在fragment中创建getter和setter来传递和获取对象。
-
@ShivamYadav 就像我在问题中所说的那样,正在调用片段默认构造函数我不知道何时因此我不知道何时调用设置器
-
实例化片段时将调用构造函数,一个好的做法是在静态方法中实例化片段并从该方法返回实例。在该实例的帮助下,您可以调用您的设置器。
标签: android android-fragments android-lifecycle