简体   繁体   中英

Retrofit 2 conflicts with Realm

After trying to send a request via Retrofit 2 I am getting Background partial concurrent mark sweep GC freed... . Probably it is because RealmObject array that I use to send in request @Body .

My API interface:

@POST("sessions/add")
Call<ResponseBody> sessionsAdd(@Body SessionVO[] options, @Header("Authorization") String token);

The request sending code:

SessionVO[] sessionVOArray= sessionsRealm.getAll();
call = serverApi.sessionsAdd(sessionVOArray, getSharedPreferenceManager().getAccessToken());

SessionVO class:

public class SessionVO extends RealmObject {

    private long sessionStartTime;
    private long sessionEndTime;

    public long getSessionStartTime() {
        return sessionStartTime;
    }

    public void setSessionStartTime(long sessionStartTime) {
        this.sessionStartTime = sessionStartTime;
    }

    public long getSessionEndTime() {
        return sessionEndTime;
    }

    public void setSessionEndTime(long sessionEndTime) {
        this.sessionEndTime = sessionEndTime;
    }
}

Realm part:

public class SessionsRealm extends RealmObject {

    private SessionVO sessionVO;

    @Ignore
    private Realm realm;

    public SessionVO getSessionVO() {
        return sessionVO;
    }

    public void setSessionVO(SessionVO sessionVO) {
        this.sessionVO = sessionVO;
    }

    public SessionsRealm(){
        realm= Realm.getDefaultInstance();
    }

    private void insert(final SessionsRealm sessionsRealm){
        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                realm.insert(sessionsRealm);
            }
        });
    }

    public SessionVO[] getAll(){
        return Realm.getDefaultInstance().where(SessionVO.class).findAll().toArray(new SessionVO[Realm.getDefaultInstance().where(SessionsRealm.class).findAll().size()]);
    }

    public boolean isEmpty(){
        return Realm.getDefaultInstance().isEmpty();
    }

    public void deleteAll(){
        Realm realm= Realm.getDefaultInstance();
        if(!realm.isEmpty()){
            realm.beginTransaction();
            realm.deleteAll();
            realm.commitTransaction();
        }
        realm.close();
    }

    public void save(Object vo){
        SessionsRealm sessionsRealm= new SessionsRealm();
        sessionsRealm.setSessionVO((SessionVO) vo);
        sessionsRealm.insert(sessionsRealm);
    }

    public void closeRealm(){
        realm.close();
    }

}

Retrofit initialization part:

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .build();

        Gson gson = new GsonBuilder()
                .setLenient()
                .create();

        Retrofit.Builder builder = new Retrofit.Builder()
                .client(okHttpClient)
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create(gson));

Retrofit retrofit = builder.build();
return Realm.getDefaultInstance().where(SessionVO.class).findAll().toArray(new SessionVO[Realm.getDefaultInstance().where(SessionsRealm.class).findAll().size()]);

This method opens two Realm instances that will never be closed, but on top of that, most of it is completely unnecessary. You can use a RealmResults as a List, so you don't even need an Array.

public RealmResults<SessionVO> getAll(Realm realm){
    return realm.where(SessionVO.class).findAll();
}

Although to send it through Retrofit with GSON, you might need to call copyFromRealm before passing it as @Body

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM