2017-09-12 2 views
0

조각 표준 방법 (Android Studio에서 생성 된 스켈레톤)을 만들었습니다. 에서 다음번들에 newInstance 데이터를 너무 많이 조각합니다 - android.os.TransactionTooLargeException

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 오버라이드 : 그래서 newInstance와 정적 메소드를

@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 수집이 매우 큰, 그래서 '이다 m 점점 예외 :

java.lang.RuntimeException가 : android.os.TransactionTooLargeException : 데이터 소포 크기 592,196 바이트

내 앱에있는 다른 곳 (이상한, json이 올바르게 전달되었지만 시스템에서 더 이상 번들로 전달할 수 없기 때문에 정확한 문제가있는 곳을 추적하기가 쉽지 않음).

메서드가 정적이기 때문에 조각을 유지하고 데이터를 전달할 수 없습니다

DataHolder.getInstance().save("eventList", eventList); 

을 그리고 데이터를 검색 : (대신 번들을 사용하는) 데이터를 저장하는 데, 그리고

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(); 
    } 
} 

:

내 솔루션, 그런 일을 데이터를 전달하기 위해 WeakReference을 사용하는 것입니다

mEventList = (List<Event>) DataHolder.getInstance().retrieve("eventList"); 

그러나 이것은 KitKat에서 작동하지 않습니다 (5.1에서 잘 작동하는 것 같습니다. 최신). 주요 문제 multidex 때문에 KitKat에서 디버깅 할 수 없으므로 디버그 컴파일은 KitKat에서 실행되지 않습니다 (릴리스에는 minifyEnabled=true 및 다중 덱 없음). 하지만 KitKat에서는 다음과 같습니다.

mEventList = (List<Event>) DataHolder.getInstance().retrieve("eventList"); 

은 항상 null입니다.

의견이 있으십니까? 내 현재의 솔루션은 빌드 버전을 확인하고 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 민간 분야, 단순히 만든됩니다 게터 :

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입니다.일부 디버깅을 한 후에는 getEventsToDraw()이 일찍 호출되어 내 콜렉션을 반환하지 않을 것이므로 아직 사용할 수있는 데이터가 없기 때문에 null을 반환합니다.

답변

0

그것은 킷캣

아니,하지 않습니다 작동합니다. 1MB IPC 트랜잭션 제한은 수년간 존재 해왔다. 그러나이 제한은 프로세스의 모든 동시 IPC 트랜잭션에 대한 것이므로 실패가 발생할 확률이 높습니다. 예를 들어, 592196은 1MB보다 작으므로 실제로 추락 한 것은 실제로 그 시간에 IPC를 사용하는 경우가 거의 없기 때문에 때때로 OK를 통해이를 수행 할 수 있습니다.

그래서 나는 이벤트의 컬렉션을 통과하지 마십시오

newInstance와 정적 메소드

있습니다. 해당 조각 모음을 되찾기 위해 조각에 필요한 최소한의 정보를 전달하십시오. 리던던트 I/O를 최소화하기 위해 프로세스 레벨 POJO 캐시를 사용하지만 필요하다면 다시 데이터베이스/네트워크/기타를 치는 것을 지원하므로 구성 변경 (프로세스 캐시가 여전히 주변에 있음)과 프로세스 종료 (사용자가 당신의 작업은 상당히 빠르므로 인스턴스 통계는 여전히 사용됩니다).

+0

"이벤트 콜렉션을 전달하지 마십시오."- 이벤트 콜렉션이 필요합니다.이 콜렉션은 커질 수 있습니다. 지도에 표시해야하므로 컬렉션이 필요합니다. 이벤트는 매우 복잡하며 각 이벤트에는 마커 클릭시 표시되어야하는 몇 가지 추가 데이터가 포함되어 있습니다. 항목을 검색 할 수있는 방법이 없으며 단편에 전달해야합니다. 내 현재 솔루션은 setter를 만들고 묶는 것에 아무 것도 전달하지 않는 것입니다 (부모 활동에 대한 매니페스트에서 이미 구성 변경이 비활성화되어 있음). – user1209216

+0

많은 양의 데이터를 작업에서 조각으로 전달하는 유효한 솔루션은 무엇입니까? 우리는 번들을 사용할 수 없으며 setter는 권장하지 않습니다. 그래서? 내 활동은 웹 서비스에서 검색된 일부 데이터 (목록)를 보유하고 있으며 서버에서 새로 고치지 않고도 표시되도록하고 싶습니다. 현재 콘텐츠를 가져와야합니다. – user1209216

+0

@ user1209216 : "큰 이벤트 일 수있는 이벤트 컬렉션을 전달해야합니다."- IMHO 메모리를 캐시로 사용하여 디스크에 저장해야합니다. 사용자의 솔루션을 사용하면 Android가 포 그라운드에 있지 않을 때 프로세스를 종료하도록 선택했기 때문에 사용자는 몇 초 동안 다른 앱으로 넘어 가서 다시 돌아와서이 데이터를 모두 잃을 수 있습니다. – CommonsWare

관련 문제