2015-12-25 15 views
5

Tôi đang cố gắng để vượt qua danh sách hàng loạt các đối tượng tùy chỉnh giữa 2 hoạt động ném ý định nhưng tôi đã nhận lỗi này và tôi không biết làm thế nào để giải quyết nó. tôi sẽ đánh giá cao nếu có ai có thể giúp tôi! Cảm ơn trước.Tôi không thể vượt qua danh sách mảng quá lớn của các đối tượng giữa 2 hoạt động?

Phương pháp trong vượt qua trong hoạt động 1'st:

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

Phương pháp trong get trong hoạt động 2'st:

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

Lỗi 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

Mảng này lớn bao nhiêu? –

+1

Truy cập liên kết này, nó có thể giúp bạn hiểu http://jyvee.com/passing-large-data-to-an-activity/ –

+0

dữ liệu nào bạn chuyển đến hoạt động tiếp theo? Nếu đó là hình ảnh sau đó sử dụng bitmap –

Trả lời

-1

Điều này có thể xảy ra rất thường xuyên khi sử dụng tính năng bổ sung ý định để vượt qua một lượng lớn dữ liệu.

lựa chọn của bạn:

  1. Định nghĩa một biến nào đó có thể được truy cập từ các biến lớp học sử dụng khác:

Bạn sẽ có mảng, nhưng ví dụ của tôi có ints:

enter image description here

Bây giờ, bạn muốn truy cập vào các ints từ một lớp học phải không? Ngay bây giờ bạn đang gửi int cho hoạt động khác thông qua ý định thêm. Thay vào đó, bạn có thể làm cho một đối tượng của MyClass và truy cập chúng theo cách đó:

enter image description here

  1. Thực hiện một sở thích chia sẻ đối tượng với dữ liệu mảng, và truy cập dữ liệu từ lớp khác.

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

Và để chỉnh sửa:

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

Không rõ nơi MyClass sẽ được lưu trữ. Viết 1 MB dữ liệu để chia sẻ sở thích mà chỉ là một tập tin xml cũng có vấn đề. –

+0

@AlexanderKulyakhtin Trên thực tế, 'MyClass' là lớp với mảng của bạn. Bây giờ, trong lớp khác của bạn, tạo một đối tượng 'MyClass' và truy cập biến thành viên. Cho tôi biết nếu nó hoạt động! –

+0

@AlexanderKulyakhtin Tuyệt vời! Bạn đã chọn phương pháp nào? –

-2

Bạn không có thể, hoặc nó sẽ làm cho ứng dụng của bạn bị đóng băng. Lưu trữ dữ liệu trong đối tượng được nhập Application để chúng tồn tại mọi lúc bạn cần.

+1

Đây thực sự là câu trả lời hay hơn câu trả lời được chấp nhận, mặc dù lượng thông tin được cung cấp có thể để tốt hơn. –

+0

Có gì sai với câu trả lời này? –

+0

Không có gì. Chỉ cần thêm một số chi tiết nữa;) –

-2

Bạn không thể chuyển đối tượng quá lớn bằng ý định.Nếu bạn muốn sử dụng dữ liệu như vậy trong nhiều hơn một hoạt động, bạn có thể định nghĩa một lớp helper như sau:

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 
    } 
} 

bạn có thể tải dữ liệu trong một hoạt động, Sau đó, khi bạn nhảy đến hoạt động khác, bạn có thể chỉ cần sử dụng :

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

Tất cả các câu trả lời được cung cấp dường như có chất lượng thấp. Vì vậy, tôi sẽ cung cấp một cái khác.

Vấn đề

Trường hợp ngoại lệ bạn đang nhận được là do thực tế là số lượng dữ liệu bạn đang cố gắng để chuyển qua một Bundle chỉ đơn giản là quá lớn.

Lưu ý: tôi đã viết một bài đăng blog về chủ đề này trên trang web của tôi, nó có chứa thông tin chi tiết hơn. Bạn có thể tìm thấy nó đây: http://neotechsoftware.com/blog/android-intent-size-limit

Solutions

Không có cách nào, bạn sẽ có thể chuyển bạn đối tượng thông qua cách tiêu chuẩn (sử dụng một Bundle hoặc Parcel), bởi vì nó là đơn giản là quá lớn. Có hai giải pháp thường được sử dụng trong các trường hợp:

  • tập tin dựa lưu trữ tạm thời và chuyển giao
  • trong bộ nhớ lưu trữ dựa và chuyển giao

dựa file

Bạn có thể lưu trữ các mảng của các đối tượng tùy chỉnh trong một tập tin và sau đó đọc nó trở lại. Tôi không khuyên bạn nên làm điều này vì nó thường chậm hơn bộ nhớ trong bộ nhớ. Tuy nhiên một kỹ thuật thường được sử dụng là sử dụng một cơ sở dữ liệu của một số loại nếu có. Tuy nhiên, việc sử dụng một cơ sở dữ liệu có một nhược điểm lớn, các đối tượng được lưu trữ trong cơ sở dữ liệu thường là các đối tượng tạm thời, do đó bạn cần loại bỏ chúng sau khi bạn đọc xong chúng. Nếu có điều gì đó sai, cơ sở dữ liệu của bạn có thể bắt đầu chứa lộn xộn. Vì vậy, bạn cần một số loại thói quen sạch sẽ. Phương pháp tốt nhất để tránh điều này có thể là viết tệp cơ sở dữ liệu (hoặc thực sự là bất kỳ tệp nào được sử dụng cho tệp này) vào thư mục bộ nhớ cache.

Trong bộ nhớ 1: (Áp dụng chẳng hạn)

lựa chọn tốt nhất (và có lẽ là cách Android ưa thích) của bạn là để lưu trữ các mảng trong Application dụ. Để làm điều này, bạn sẽ cần phải tạo một lớp và làm cho nó mở rộng Application. Trong lớp này, bạn tạo một trường công khai để viết và đọc mảng.

public class App extends Application { 

    public ArrayList<YourObject> objects; 

} 

Bạn có thể đọc và ghi vào trường này bằng cách lấy ví dụ Application.

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

Đừng quên đăng ký lớp học mở rộng Application trong tệp manifest.xml!Tại sao tính năng này hoạt động: Thao tác này hoạt động vì cá thể Application sẽ không bị hủy giữa các Hoạt động khác nhau, nó có vòng đời độc lập với giao diện người dùng.

Trong bộ nhớ 2 (singleton)

Một lựa chọn khác là sử dụng mô hình singleton hoặc tạo ra một lớp với các lĩnh vực tĩnh. Ví dụ dưới đây thể hiện mẫu đơn.

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; 

note Rất quan trọng về lưu trữ đối tượng trong bộ nhớ: Giả định rằng ứng dụng của bạn ở chế độ nền và bạn lưu trữ một số đối tượng trong Application dụ (hoặc trong một container singleton) để sau đó khôi phục lại nó. Nếu hệ thống Android quyết định giết ứng dụng của bạn vì nó cần giải phóng bộ nhớ cho một ứng dụng khác, đối tượng của bạn sẽ bị hủy. Bây giờ phần quan trọng, nếu người dùng quay trở lại ứng dụng của bạn, hệ thống Android sẽ tạo lại Activity bị phá hủy và chuyển một "trạng thái lưu-thể hiện" không rỗng "Bundle" sang phương thức onCreate(). Bạn có thể giả định vào thời điểm này (vì Bundle là không null) các đối tượng lưu trữ trong bộ nhớ của bạn tồn tại, tuy nhiên điều này không đúng! Kết luận: Luôn kiểm tra xem các đối tượng được lưu trữ có không null không!

Các vấn đề liên quan