1

Loopers と Realm に問題があります。

ActivityonCreate()でインスタンス化してからPresenter、パブリック メソッドの 1 つを呼び出します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このコンテキストでの私の活動であることに注意してください。

私の問題は、それonChange()時々呼び出されることであり、それが呼び出されると、UI スレッドがブロックされます (そして、最終的に a が引き起こされます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;
                }

            }
        });
4

1 に答える 1

1

UI スレッドは Looper スレッドです ( looper がありますLooper.getMainLooper())。これは、自動更新があることを意味します。ただし、自動更新とは、ChangeListenerに追加した がRealmObject、一度だけではなく、基になるテーブルが変更されるたびに呼び出されることを意味します。

(また、RealmChangeListeners は Realm によって弱い参照で保持され、も同様に保持されることに注意する必要ContextがありますRealmObject。そのため、自動更新と変更リスナーを GC を通じてもそのまま維持するには、フィールド参照として保持する必要があります

findFirst()ID で要素が見つからない場合は null を返し、それ以外の場合はすぐに要素を返すことにも注意してください)。

playerViewContract.initWithCourseDetails(element);そのため、何をしても、何度も何度も実行され、最終的にクラッシュするように思えます。

私はあなたの質問に答えたことを願っていますか?

于 2016-09-01T14:23:20.970 に答える