gpt4 book ai didi

android - Realm 和 Looper 恶作剧

转载 作者:行者123 更新时间:2023-11-30 01:02:01 27 4
gpt4 key购买 nike

我在使用 Loopers 和 Realm 时遇到了麻烦。

我有一个 Activity 在 onCreate() 中实例化它的 Presenter,然后调用它的公共(public)方法之一 initFirstLaunch() :

RealmChangeListener<CourseDetailed> listener = new RealmChangeListener<CourseDetailed>() {
@Override
public void onChange(CourseDetailed element) {
Log.i("renaud", "courseDetailed.addChangeListener onChange");
computeTableOfContent(element);
Log.i("renaud", "1");
playerViewContract.initWithCourseDetails(element);
Log.i("renaud", "2");
}
};

public void initFirstLaunch() {

courseDetailed = realm.where(CourseDetailed.class).contains("_id", courseId).findFirst();

if (courseDetailed == null) {
courseDetailed = realm.createObject(CourseDetailed.class, courseId);
}

courseDetailed.addChangeListener(listener);

Api.getInstance().backend.getCourse(courseId).enqueue(new CustomRetrofitCallBack<CourseDetailed>(playerViewContract) {
@Override
public void onResponseReceived(final CourseDetailed response) {

Realm.getDefaultInstance().executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(response);
}
});
}
});
}

请注意,playerViewContract 是我在此上下文中的 Activity 。

我的问题是 onChange()有时 调用,当它调用时它会阻塞我的 UI 线程(并最终引发 OutOfMemoryError ).我的猜测是我不在循环线程中,但是当我在任何地方调用 Looper.prepare() 时它崩溃了,说我已经在循环线程中了。

发生了什么事?

谢谢


编辑:添加 initWithCourseDetailed 代码

@Override
public void initWithCourseDetails(final CourseDetailed detailed) {

Log.i("renaud", "initWithCourseDetails");

mDrawer.post(new Runnable() {
@Override
public void run() {

String title = detailed.getName();
String subtitle = detailed.getCompany().getName();

if (detailed.getThumbnail() != null) {

String picUrl = AppConstants.SERVER_URL + "/api/" + detailed.getThumbnail();

final LinearLayout l = (LinearLayout) mNavigationView.findViewById(R.id.layout);
Picasso.with(ModulePlayerActivity.this)
.load(picUrl)
.config(Bitmap.Config.RGB_565)
.into(new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
l.setBackground(new BitmapDrawable(getResources(), bitmap));
}

@Override
public void onBitmapFailed(Drawable errorDrawable) {
}

@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {

}
});
}

TextView nameTv = (TextView) mNavigationView.findViewById(R.id.drawer_header_name);
nameTv.setText(title);

TextView jobTv = (TextView) mNavigationView.findViewById(R.id.drawer_header_job);
jobTv.setText(subtitle);

supportInvalidateOptionsMenu();

}
});
}

编辑:更正

Api.getInstance().backend.getCourse(courseId).enqueue(new CustomRetrofitCallBack<CourseDetailed>(playerViewContract) {
@Override
public void onResponseReceived(final CourseDetailed response) {

//TEST
Realm realm = null;
try {
realm = Realm.getDefaultInstance();
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(response);
}
});
} finally {
if (realm != null) {
realm.close();
}
realm = null;
}

}
});

最佳答案

UI线程是一个Looper线程(它有looper Looper.getMainLooper()),这意味着它有autoupdate。然而,自动更新意味着您添加到 RealmObject 中的 ChangeListener 将在底层表被修改时被调用,而不只是一次。

(我还应该注意到,RealmChangeListener 被 Realm 的 Context 保留为弱引用,RealmObject 也是如此,所以 to keep the autoupdate and the change listener intact even through GC, it has to be kept as a field reference

虽然还值得注意的是,findFirst() 可以在通过 ID 找不到元素时返回 null,否则立即返回该元素。)

所以在我看来,无论 playerViewContract.initWithCourseDetails(element); 做了什么,它都会一次又一次地执行并最终崩溃。

希望我回答了您的问题?

关于android - Realm 和 Looper 恶作剧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39273666/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com