Vì Hans Boehm trong Google I/O '17 talk "How to Manage Native C++ Memory in Android" đề xuất tôi sử dụng lớp PhantomReference
để đảm bảo các đồng nghiệp gốc bị xóa đúng cách.Xóa đồng đẳng gốc với lớp chung PhantomReference
Trong video được liên kết tại 18 min 57 sec, anh ấy hiển thị ví dụ về việc thực hiện đối tượng tự đăng ký lớp PhantomReference
cho loại đó. Lớp học PhantomReference
này, sau đó anh hiển thị ở số 19 min 49 sec. Vì vậy, tôi sao chép cách tiếp cận của mình cho đối tượng ví dụ của tôi. Xem bên dưới.
Trong khi phương pháp này hoạt động tốt, nó không mở rộng. Tôi sẽ cần tạo một số lượng đối tượng và tôi không tìm được cách tạo lớp cơ sở (hoặc cho đối tượng của tôi hoặc lớp cơ sở PhantomReference
) sẽ lấy bất kỳ đối tượng nào và xử lý việc xóa gốc một cách chính xác.
Làm cách nào để tạo một lớp chung cơ sở PhantomReference
mà có thể gọi phương thức tĩnh gốc trên đối tượng được cung cấp?
Tôi đã cố gắng biến đổi phương thức xóa chung PhantomReference
nhưng phương pháp xóa tĩnh gốc cản trở việc triển khai.
My WorkViewModel
import android.databinding.*;
public class WorkViewModel extends BaseObservable
{
private long _nativeHandle;
public WorkViewModel(Database database, int workId)
{
_nativeHandle = create(database.getNativeHandle(), workId);
WorkViewModelPhantomReference.register(this, _nativeHandle);
}
private static native long create(long databaseHandle, int workId);
static native void delete(long nativeHandle);
@Bindable
public native int getWorkId();
public native void setWorkId(int workId);
}
WorkViewModelPhantomReference
import java.lang.ref.*;
import java.util.*;
public class WorkViewModelPhantomReference extends PhantomReference<WorkViewModel>
{
private static Set<WorkViewModelPhantomReference> phantomReferences = new HashSet<WorkViewModelPhantomReference>();
private static ReferenceQueue<WorkViewModel> garbageCollectedObjectsQueue = new ReferenceQueue<WorkViewModel>();
private long _nativeHandle;
private WorkViewModelPhantomReference(WorkViewModel workViewModel, long nativeHandle)
{
super(workViewModel, garbageCollectedObjectsQueue);
_nativeHandle = nativeHandle;
}
public static void register(WorkViewModel workViewModel, long nativeHandle)
{
phantomReferences.add(new WorkViewModelPhantomReference(workViewModel, nativeHandle));
}
public static void deleteOrphanedNativePeerObjects()
{
WorkViewModelPhantomReference reference;
while((reference = (WorkViewModelPhantomReference)garbageCollectedObjectsQueue.poll()) != null)
{
WorkViewModel.delete(reference._nativeHandle);
phantomReferences.remove(reference);
}
}
}
Tôi tin rằng ngay lập tức phương pháp này không mở rộng quy mô. Nhưng tôi không hiểu vấn đề thứ hai của bạn rằng bạn "* chưa tìm ra cách tạo lớp cơ sở ... sẽ lấy bất kỳ đối tượng nào và sẽ xử lý việc xóa nội dung chính xác *". Bạn có một giải pháp làm việc bao gồm hai lớp. Vấn đề gì mà lớp cơ sở giả thuyết đó giải quyết và làm thế nào? – Holger
@Holger cảm ơn câu trả lời của bạn. Xin giải thích cho tôi vấn đề quy mô? Đó là những gì tôi cố gắng giải quyết với một lớp cơ sở giả định. Tôi đã có rất nhiều đối tượng như vậy và cho mỗi người trong số những người tôi đã tạo ra một lớp ma thứ hai. Với một lớp cơ sở, tôi muốn giải quyết rằng tôi sẽ không cần phải tạo thêm một lớp hoặc làm cho nó đơn giản đến nỗi tôi chỉ cần định nghĩa kiểu đó. –
Đợi — bạn tạo một lớp ma mới cho từng đối tượng bạn tạo? Hoặc bạn có ý gì với "mỗi người trong số đó"? – Holger