Ich habe Probleme mit Looper und Realm.Realm and Looper shenanigans
ich eine Activity
haben, die seine Presenter
in onCreate instanziiert() und dann einer seiner öffentlichen Methode aufrufen 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);
}
});
}
});
}
zur Kenntnis, dass playerViewContract
meine Tätigkeit in diesem Zusammenhang ist.
Mein Problem ist, dass onChange()
ist manchmal genannt, und wenn es blockiert mein UI Thread (und provoques eventualy eine OutOfMemoryError
). Meine Vermutung war, dass ich nicht in einem Looper-Thread war, aber wenn ich Looper.prepare()
irgendwo anrufe, stürzt es ab, sagend, dass ich bereits in einem bin.
Was passiert?
Dank
Edit: Bearbeiten initWithCourseDetailed Code
@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();
}
});
}
Hinzufügen: Korrektur
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;
}
}
});
Die Dinge sind mir noch nicht klar. Ich protokolliere den Aufruf von 'initWithCourseDetails', und es springt meistens nicht, manchmal sehe ich 1 Protokoll. Ich protokolliere auch den 'OnChange'-Aufruf, der immer einmal aufgerufen wird. Ich verstehe, dass es jedes Mal aufgerufen wird, wenn mein "RealmModel" aktualisiert wird, das ist das Verhalten, nach dem ich suche. Ich verstehe nicht, warum der Aufruf von 'initWithCourseDetails' meinen Modellwechselgedanken betrifft, es ist eine reine Ansichtsmethode. (Ich füge 'initWithCourseDetails' Code hinzu) –
Ich habe gerade Ihren 'RealmChangeListener' Punkt bekommen, ich habe ihn geändert, um ein Feld meines Presenters zu sein. Könntest du mir einfach nochmal erklären warum du denkst dass 'onChange' infinit mal heißt? Und ich merke, dass ich nicht danke für die Beantwortung von mir gesagt habe, das ist sehr geschätzt Ich versichere Ihnen –
Nun technisch, wenn Sie die Tabelle nur einmal ändern, dann sollte es nur einmal aufgerufen werden. Wenn es jedoch nur einmal aufgerufen wird, sollte Ihr Code nicht abstürzen, es sei denn, Ihr 'computeTableOfContent (Element);' oder 'initWithCourseDetails' hängt irgendwie in einer Schleife fest ...' createObject() 'sollte nicht funktionieren, außer Sie ' In einer Transaktion bin ich ein wenig unzufrieden mit diesem Code. Kann ich Ihnen empfehlen, meinen [Artikel] zu lesen (http: // medium.com/@ Zhuinden/how-to-use-Realm-für-Android-wie-ein-Champ-und-wie-sagen-wenn-du-tun-es-falsch-ac4f66b7f149) auf Realm-Nutzung? – EpicPandaForce