【发布时间】:2017-09-12 11:35:02
【问题描述】:
我已经创建了片段标准方式(Android Studio 生成的骨架)。所以我有 newInstance 静态方法:
public static EventsMapFragment newInstance(List<Event> eventList, String accessToken, String tokenType, String cityId, boolean isMessage)
{
Bundle args = new Bundle();
args.putString("events", new Gson().toJson(eventList));
EventsMapFragment fragment = new EventsMapFragment();
///...........
fragment.setArguments(args);
return fragment;
}
然后,onCreate override 我需要检索我的收藏,非常标准的方式:
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (getArguments() != null)
{
String json = getArguments().getString("events");
Type type = new TypeToken<List<Event>>(){}.getType();
mEventList = new Gson().fromJson(json, type);
}
问题是 eventList 集合非常大,所以我得到了异常:
java.lang.RuntimeException: android.os.TransactionTooLargeException: 数据包大小592196字节
在我的应用程序中的其他地方(奇怪,json 被正确传递,但系统不允许传递更多内容到 bundle,很难跟踪确切的问题所在)。
因为newInstance() 方法是静态的,所以我无法创建保留片段并将数据传递给它(在这种情况下我实际上不知道该怎么做)。
我的解决方案是使用WeakReference 来传递数据,类似这样:
public class DataHolder
{
private static final DataHolder holder = new DataHolder();
Map<String, WeakReference<Object>> data = new HashMap<>();
public static DataHolder getInstance() {return holder;}
public void save(String id, Object object)
{
data.put(id, new WeakReference<>(object));
}
public Object retrieve(String id)
{
WeakReference<Object> objectWeakReference = data.get(id);
return objectWeakReference.get();
}
}
然后,存储数据(而不是使用 bundle):
DataHolder.getInstance().save("eventList", eventList);
并检索数据:
mEventList = (List<Event>) DataHolder.getInstance().retrieve("eventList");
但是,这在 KitKat 上不起作用(它似乎在 5.1 和更高版本上运行良好)。主要问题我无法在 KitKat 上调试,因为 multidex,所以调试编译甚至不会在 KitKat 上运行(版本有 minifyEnabled=true 并且没有 multi dex)。但在 KitKat 上,这似乎是:
mEventList = (List<Event>) DataHolder.getInstance().retrieve("eventList");
始终为空。
你有什么想法吗?我目前的解决方案是检查构建版本并将 json 传递给 KitKat 上的捆绑包(它适用于 KitKat,问题是 7.0 及更高版本)并在较新的 Android 版本上使用 WeakReference。
但实际上我对此并不满意。
[编辑] 所以我最后一次尝试是从父活动中获取事件集合。在主要活动中,我有以下代码(一个应用程序抽屉菜单单击):
if (menuId == R.id.nav_events_map)
{
eventsToDraw = Lists.newArrayList(Collections2.filter(events,x->!Utils.isGeojsonEmpty(x.getGeojson())));
//....................
if(eventsToDraw.size() >0)
{
mFragment = EventsMapFragment.newInstance();
ReplaceFragment(mFragment);
}
else
{
mFragment = NoDataFragment.newInstance(getString(R.string.message_no_events));
ReplaceFragment(mFragment);
}
}
eventsToDraw 是私有字段,我只是创建了 getter:
public List<Event> getEventsToDraw()
{
return eventsToDraw;
}
然后,在我的地图片段中:
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
//Map initialization stuff
//....................
mEventList = ((MainActivity)getActivity()).getEventsToDraw();
//Draw on map stuff etc
}
问题是我总是得到mEventList null。经过一些调试,我注意到 getEventsToDraw() 被提前调用,所以它不会返回我的集合,它返回 null,因为还没有可用的数据。
【问题讨论】:
标签: java android exception transactions bundle