2015-12-25 19 views
5

Próbuję przekazać listę tablic niestandardowego obiektu między 2 działaniami, ale zamierzam, ale mam ten błąd i nie wiem jak go rozwiązać. doceniam, jeśli ktoś może mi pomóc! Z góry dziękuję.Nie mogę przekazać zbyt dużej listy obiektów między 2 aktywnościami?

Sposób piłkę aktywności 1'st:

i.putParcelableArrayListExtra("key", (ArrayList<? extends Parcelable>) result); 
startActivity(i); 

Metoda Get aktywności 2'st:

Intent i = getIntent(); 
ArrayList<ItemObjects> list = i.getParcelableArrayListExtra("key"); 

Error Log:

12-25 09:11:49.546 17742-17742/com.example.baha.myapplication E/AndroidRuntime: FATAL EXCEPTION: main 
Process: com.example.baha.myapplication, PID: 17742 
java.lang.RuntimeException: Failure from system 
    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1514) 
    at android.app.Activity.startActivityForResult(Activity.java:3917) 
    at android.app.Activity.startActivityForResult(Activity.java:3877) 
    at android.app.Activity.startActivity(Activity.java:4200) 
    at android.app.Activity.startActivity(Activity.java:4168) 
    at com.example.baha.myapplication.splash$GetMarkets.onPostExecute(splash.java:127) 
    at com.example.baha.myapplication.splash$GetMarkets.onPostExecute(splash.java:62) 
    at android.os.AsyncTask.finish(AsyncTask.java:651) 
    at android.os.AsyncTask.-wrap1(AsyncTask.java) 
    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.app.ActivityThread.main(ActivityThread.java:5417) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Caused by: android.os.TransactionTooLargeException: data parcel size 12404332 bytes 
    at android.os.BinderProxy.transactNative(Native Method) 
    at android.os.BinderProxy.transact(Binder.java:503) 
    at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2657) 
    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1507) 
    at android.app.Activity.startActivityForResult(Activity.java:3917) 
    at android.app.Activity.startActivityForResult(Activity.java:3877) 
    at android.app.Activity.startActivity(Activity.java:4200) 
    at android.app.Activity.startActivity(Activity.java:4168) 
    at com.example.baha.myapplication.splash$GetMarkets.onPostExecute(splash.java:127) 
    at com.example.baha.myapplication.splash$GetMarkets.onPostExecute(splash.java:62) 
    at android.os.AsyncTask.finish(AsyncTask.java:651) 
    at android.os.AsyncTask.-wrap1(AsyncTask.java) 
    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:148) 
    at android.app.ActivityThread.main(ActivityThread.java:5417) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
+0

Jak duża jest ta tablica? –

+1

To łącze może pomóc zrozumieć http://jyvee.com/passing-large-data-to-an-activity/ –

+0

jakie dane przekazujesz do następnej czynności ?, jeśli jest to obraz, użyj mapy bitowej –

Odpowiedz

-1

Może się to zdarzyć bardzo często, gdy używasz dodatków intencyjnych do przesyłania dużych ilości danych.

Twoje opcje:

  1. zdefiniować zmienną publiczną, które mogą być dostępne z innych zmiennych klasowych używając:

byś tablic, ale mój przykład ma ints:

enter image description here

Teraz chcesz uzyskać dostęp do tych stron z innej klasy, prawda? W tej chwili wysyłasz int do innej działalności za pomocą intencji dodatkowej. Zamiast tego można uczynić przedmiotem MyClass i dostęp do nich w ten sposób:

enter image description here

  1. dokonać wspólne preferencje obiekt z danymi tablicę, a dostęp do danych z inna klasa.

    Preferencje SharedPreferences = this.getSharedPreferences ("com.example.app", Context.MODE_PRIVATE);

I edycji:

prefs.edit().putInt(INT).apply(); 
+2

Nie wiadomo, gdzie będzie przechowywany ten MyClass. Zapisywanie 1 MB danych do współużytkowanej preferencji, która jest tylko plikiem xml, również jest problematyczne. –

+0

@AlexanderKulyakhtin Właściwie 'MyClass' jest klasą z twoją tablicą. Teraz, w twojej drugiej klasie, stwórz obiekt 'MyClass' i uzyskaj dostęp do zmiennej członkowskiej. Daj znać czy działa! –

+0

@AlexanderKulyakhtin Great! Którą metodę wybrałeś? –

-2

Nie możesz, albo sprawi, że aplikacja się zawiesi. Przechowuj dane w otrzymanym obiekcie, aby istniały przez cały czas, którego potrzebujesz.

+1

Jest to w rzeczywistości lepsza odpowiedź niż zaakceptowana odpowiedź, chociaż ilość dostarczonych informacji może bądź lepszy. –

+0

Co jest nie tak z tą moją odpowiedzią? –

+0

Nic. Po prostu dodaj trochę więcej szczegółów;) –

-2

Nie można przekazać zbyt dużego obiektu za pomocą intencji.Jeśli chcesz za pomocą tych danych w więcej niż jednej czynności, można zdefiniować klasę pomocniczą tak:

public class MyData { 
    private static MyData sInstance = new MyData(); 
    public static MyData get() { return sIntance; } 

    private ArrayList<> data; 
    public List<> getData() { return data; } 
    public void loadData() { 
     // load data 
    } 
} 

można załadować danych w jednej czynności, Następnie po przejściu do innej aktywności, możesz po prostu użyć :

ArrayList<> data = MyData.get().getData(); 
4

Wszystkie odpowiedzi udzielone wydawać się nieco niskiej jakości. Tak więc dostarczę kolejną.

Problem

Wyjątkiem jesteś coraz to spowodowane faktem, że ilość danych, którą próbujesz przekazać poprzez pakiet jest po prostu zbyt duża.

Uwaga: pisałem na blogu na ten temat na mojej stronie internetowej, zawiera bardziej szczegółowe informacje. Można go znaleźć tutaj: http://neotechsoftware.com/blog/android-intent-size-limit

Solutions

Nie sposób będzie można przenieść jesteś obiektem poprzez standardowy sposób (za pomocą Bundle lub paczka), ponieważ jest po prostu zbyt duży. Istnieją dwa rozwiązania, które są często stosowane w tych przypadkach:

  • Plik oparty czasowego składowania i transferu

na podstawie pliku w pamięci oparte przechowywania i przekazywania

Mogłabyś przechowaj tablicę niestandardowych obiektów w pliku, a następnie odczytaj ją. Nie polecam robić tego jako ogólnie wolniejszego niż przechowywanie w pamięci. Jednak często stosowaną techniką jest użycie jakiejś bazy danych, jeśli dotyczy. Korzystanie z bazy danych ma jednak poważną wadę, dlatego obiekty przechowywane w bazie danych są często obiektami tymczasowymi, więc należy je usunąć po zakończeniu ich czytania. Jeśli coś pójdzie nie tak, twoja baza danych może zacząć zawierać bałagan. Więc potrzebujesz jakiegoś czystego rutyny. Najlepszą metodą uniknięcia tego jest prawdopodobnie zapisanie pliku bazy danych (lub faktycznie dowolnego pliku używanego do tego) do katalogu pamięci podręcznej.

w pamięci 1 (przykład aplikacja)

Najlepszym rozwiązaniem (i prawdopodobnie korzystny sposób Android) jest przechowywanie tablicy na przykład Application. Aby to zrobić, musisz utworzyć klasę i rozszerzyć ją na Application. W tej klasie tworzysz publiczne pole do zapisu i odczytu tablicy.

public class App extends Application { 

    public ArrayList<YourObject> objects; 

} 

Możesz czytać i pisać w tym polu, uzyskując instancję Application.

App app = (App) getApplicationContext(); 
app.objects = yourArrayList; 

Nie zapomnij zarejestrować swoją rozszerzoną Application klasę w pliku manifest.xml!Dlaczego to działa: Działa to, ponieważ instancja Application nie zostanie zniszczona między różnymi działaniami, ma cykl życia niezależny od interfejsu użytkownika.

w pamięci 2 (jednoelementowy)

Innym rozwiązaniem jest użycie wzorzec Singleton lub tworzyć klasy z pól elektrostatycznych. Poniższy przykład demonstruje wzór singleton.

public class DataContainer { 

    private static DataContainer instance = null; 

    public static DataContainer getInstance(){ 
     /** 
     * Synchronizing this method is not needed if you only use it in 
     * Activity life-cycle methods, like onCreate(). But if you use 
     * the singleton outside the UI-thread you must synchronize this 
     * method (preferably using the Double-checked locking pattern). 
     */ 
     return instance != null?instance: (instance = new DataContainer()); 
    } 

    public ArrayList<YourObject> objects; 

} 


DataContainer.getInstance().objects = yourArray; 

Bardzo ważna uwaga na w pamięci przechowywania obiektu: Załóżmy, że aplikacja jest w tle i przechowywane jakiś przedmiot na przykład Application (lub w jednoelementowy pojemnik), aby odtworzyć ją później. Jeśli system Android zdecyduje się zabić twoją aplikację, ponieważ musi zwolnić trochę pamięci dla innej aplikacji, twoje obiekty zostaną zniszczone. Teraz ważną częścią, jeśli użytkownik powraca do swojej aplikacji, system Android ponownie tworzy zniszczone Activity i przekazuje niezerowy "zapisany stan instancji" Bundle do metody onCreate(). Możesz założyć, że w tym momencie (ponieważ Bundle ma wartość inną niż null), twoje przechowywane w pamięci obiekty istnieją, to jednak nie jest prawda! Wniosek: Zawsze sprawdź, czy przechowywane obiekty nie mają wartości NULL!