2014-10-07 11 views
9

Tôi hiện đang viết một ứng dụng kéo một loạt các thời gian dài từ máy chủ qua json và sau đó chuyển danh sách đó từ một hoạt động này sang hoạt động khác. Bộ xương cơ bản trông như thế này:Sane cách để đi từ ArrayList <Long> thông qua Intent

public void onResponse(Map result) 
{ 
    ArrayList handles= (ArrayList)result.get("fileHandles"); 

    Intent intent = new Intent(FirstActivity.this, SecondActivity.class); 
    intent.putExtra("handles", handles); 
} 

Vì vậy, vấn đề đầu tiên trở nên rõ ràng, các phương pháp duy nhất cho putExtra là putIntegerArrayListExtra, putStringArrayListExtra, putCharSequenceArrayListExtra, và putParcelableArrayListExtra. Suy nghĩ Long có thể sẽ được chuyển nhượng, tôi đã sai nó không hoạt động (ngay cả khi tôi sử dụng ArrayList<Long>). Tiếp theo tôi nghĩ rằng tôi chỉ cần vượt qua một [] dài, tuy nhiên tôi thấy không có chuyển đổi thẳng về phía trước để đi từ ArrayList<Long> đến dài [] rằng intent.putExtra sẽ chấp nhận. Đây là giải pháp cuối cùng tôi đã kết thúc với:

ArrayList handles= (ArrayList)result.get("fileHandles"); 
long [] handleArray = new long[handles.size()]; 
for (int i = 0; i < handles.size(); i++) 
{ 
    handleArray[i] = Long.parseLong(handles.get(i).toString()); 
} 

Rõ ràng điều này dường như hơi vô lý đối với tôi, nhưng mọi chuyển đổi khác tôi đã thử dường như phàn nàn vì một lý do nào đó. Tôi đã nghĩ về việc suy nghĩ lại việc serialization của tôi để có vấn đề được chăm sóc trước khi tôi nhận được đến thời điểm này, nhưng tôi thấy nó kỳ lạ mà đi qua ArrayList<Long> từ hoạt động đến hoạt động có thể rất khó khăn. Có một giải pháp rõ ràng hơn tôi đang thiếu?

+0

FWIW: 'Long.parseLong (handles.get (i) .toString());' có thể được viết là '(long) (Long) handles.get (i)' ('(dài)' thực sự là tùy chọn trong ngữ cảnh) khi nguồn là một 'ArrayList '. Nó sử dụng một dowcast và sau đó là một (hoặc ngầm) un-autobox rõ ràng thay vì Long-> String-> long. – user2864740

+0

@ user2864740 Vấn đề là 'handles.get (i)' đang cho tôi trở lại một số nguyên nếu nó dưới 2 tỷ hoặc hơn, kết quả trong một dàn diễn viên không hợp lệ nếu tôi sử dụng mã đó. –

Trả lời

9

Bạn có thể sử dụng số này làm số Serializable bổ sung. ArrayListSerializableLong kéo dài Number mà cũng thực hiện Serializable:

// Put as Serializable 
i.putExtra("handles", handles); 

// Unfortunately you'll get an unsafe cast warning here, but it's safe to use 
ArrayList<Long> handles = (ArrayList<Long>) i.getSerializableExtra("handles");  
+0

Tôi không thấy 'putSerializable' như một tùy chọn trên' Intent'. –

+0

Xin lỗi về điều đó, tôi đã nhìn vào 'Bundle', không phải' Intent'. Xem chỉnh sửa. :) – kcoppock

+0

OK, đơn giản hơn nhiều, cảm ơn rất nhiều. Cảm thấy tốt để xóa tất cả những mã khủng khiếp mà tôi vừa viết. –

2

Hai lựa chọn: Sử dụng Parcelable hoặc Serializable

trong:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class); 
intent.putExtra("handles", new FileHandles(handles)); 

ra:

FileHandles handles = intent.getParcelableExtra("handles"); 

đối tượng:

import android.os.Parcel; 
import android.os.Parcelable; 

import java.util.ArrayList; 
import java.util.List; 

public class FileHandles implements Parcelable { 

    private final List<Long> fileHandles; 

    public FileHandles(List<Long> fileHandles) { 
     this.fileHandles = fileHandles; 
    } 

    public FileHandles(Parcel in) { 
     int size = in.readInt(); 
     long[] parcelFileHandles = new long[size]; 
     in.readLongArray(parcelFileHandles); 
     this.fileHandles = toObjects(size, parcelFileHandles); 
    } 

    private List<Long> toObjects(int size, long[] parcelFileHandles) { 
     List<Long> primitiveConv = new ArrayList<Long>(); 
     for (int i = 0; i < size; i++) { 
      primitiveConv.add(parcelFileHandles[i]); 
     } 
     return primitiveConv; 
    } 

    public List<Long> asList() { // Prefer you didn't use this method & added domain login here, but stackoverflow can only teach so much.. 
     return fileHandles; 
    } 

    @Override 
    public int describeContents() { 
     return 0; 
    } 

    @Override 
    public void writeToParcel(Parcel dest, int flags) { 
     dest.writeInt(fileHandles.size()); 
     dest.writeLongArray(toPrimitives(fileHandles)); 
    } 

    private static long[] toPrimitives(List<Long> list) { 
     return toPrimitives(list.toArray(new Long[list.size()])); 
    } 

    public static long[] toPrimitives(Long... objects) { 
     long[] primitives = new long[objects.length]; 
     for (int i = 0; i < objects.length; i++) 
      primitives[i] = objects[i]; 

     return primitives; 
    } 

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { 
     @Override 
     public FileHandles createFromParcel(Parcel in) { 
      return new FileHandles(in); 
     } 

     @Override 
     public FileHandles[] newArray(int size) { 
      return new FileHandles[size]; 
     } 
    }; 
} 

Serializable (buộc phải sử dụng ArrayList mà thực hiện Serializable (List không)

trong:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class); 
    intent.putExtra("handles", new ArrayList<Long>()); 

ra:

ArrayList handles = (ArrayList) intent.getSerializableExtra("handles"); 
+0

Cảm ơn câu trả lời.Tôi nhìn vào lựa chọn có thể thửa đổi nhưng nó có vẻ tệ hơn sự chuyển đổi xấu xí. Các tùy chọn 'Serializable' có vẻ là giải pháp dễ nhất cho vấn đề. –

+0

'Serializable' với việc sử dụng bắt buộc' ArrayList' là tùy chọn dễ dàng hơn. 'Parcelable' là phiên bản Android của' Serializable' http://developer.android.com/reference/android/os/Parcelable.html được tối ưu hóa cho các tập dữ liệu di động và lớn. Tôi sẽ luôn luôn khuyên bạn nên 'Serializable' nhưng nếu bạn có 1000 của các mục trong danh sách của bạn và vượt qua nó xung quanh rất nhiều, tôi sẽ khuyên bạn nên nghiên cứu' Parcelable' để xem xét như là một đạt được hiệu suất – Blundell

+0

Cảm ơn, tôi sẽ ghi nhớ nó. Tôi nghĩ rằng nó sẽ được OK trong trường hợp sử dụng của tôi, nó không quá 5-10 giá trị dài. –

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