Android realm大型RealmResults在修改数据时阻止UI线程
我一直在尝试用大型数据集测试Realm的性能。它似乎在插入和查询时表现得非常好,结果集大小适中,但一旦结果集很大,它就开始影响主线程,即使实际写入是异步运行的。我已经编写了一个测试活动,显示了下面的问题。请注意:Android realm大型RealmResults在修改数据时阻止UI线程,android,realm,Android,Realm,我一直在尝试用大型数据集测试Realm的性能。它似乎在插入和查询时表现得非常好,结果集大小适中,但一旦结果集很大,它就开始影响主线程,即使实际写入是异步运行的。我已经编写了一个测试活动,显示了下面的问题。请注意: Attendee是一个主键为“name”且索引整型字段为“age”的模型 该视图有一个显示计数的文本字段,一个在单击时调用reloadData的按钮,以及一个交互元素(我使用了一个滑块),可以在使用它时查看跳过的帧 如果更改列表的查询,使其导致更小的结果集(而不是更少,然后更改为equ
package com.test.ui;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.test.R;
import com.test.model.Attendee;
import io.realm.OrderedRealmCollection;
import io.realm.Realm;
import io.realm.RealmAsyncTask;
import io.realm.RealmRecyclerViewAdapter;
import io.realm.RealmResults;
public class LoginActivity extends AppCompatActivity {
private static final int RECORD_COUNT = 200000;
private static final int TRANSACTION_SIZE = 1000;
private RealmAsyncTask mTask = null;
private RecyclerView mAttendeeList;
private TextView mCountText;
private Button mButton;
private Handler handler;
private Realm mRealm;
private RealmResults<Attendee> mActualList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mRealm = Realm.getDefaultInstance();
mCountText = (TextView) findViewById(R.id.count_text);
mButton = (Button) findViewById(R.id.button);
handler = new Handler(Looper.getMainLooper());
setCountText((int) mRealm.where(Attendee.class).count());
mActualList = mRealm.where(Attendee.class).lessThan("age", 20).findAllAsync();
mRealm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.deleteAll();
setCountText(0);
}
}, new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
mButton.setEnabled(true);
}
}, new Realm.Transaction.OnError() {
@Override
public void onError(Throwable error) {
String text = "Error deleting";
Log.e("ANRTEST", text, error);
Toast.makeText(LoginActivity.this, text, Toast.LENGTH_LONG).show();
}
});
}
private void setCountText(int size) {
mCountText.setText(String.format("Count: %s", size));
}
@Override
protected void onDestroy() {
mActualList = null;
if(mTask != null && !mTask.isCancelled()) {
mTask.cancel();
mTask = null;
}
if(mRealm != null && !mRealm.isClosed()) {
mRealm.close();
}
super.onDestroy();
}
public void loadData(final TimerUtil t) {
Realm.Transaction.OnError onError = new Realm.Transaction.OnError() {
@Override
public void onError(Throwable error) {
mTask = null;
Toast.makeText(LoginActivity.this, "Finished should show now", Toast.LENGTH_LONG).show();
}
};
Realm.Transaction.OnSuccess onSuccess = new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
mTask = null;
int count = (int) mRealm.where(Attendee.class).count();
if (count >= RECORD_COUNT) {
Log.v("ANRTEST", String.format("Finished in %s seconds", t.currentElapsed() / 1000));
mButton.setEnabled(false);
} else {
handler.postDelayed(new Runnable() {
@Override
public void run() {
loadData(t);
}
}, 300);
}
setCountText(count);
}
};
mTask = mRealm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
int innerStart = (int) realm.where(Attendee.class).count();
int i = 0;
while (i < TRANSACTION_SIZE && i + innerStart < RECORD_COUNT) {
Attendee attendee = new Attendee();
int innerValue = innerStart + i;
attendee.name = "name " + (innerValue + 1);
attendee.age = innerValue % 50;
realm.insert(attendee);
i++;
}
Log.v("ANRTEST", String.format("Checkpoint %s (%s seconds)", Math.min(innerStart + i, RECORD_COUNT), t.currentElapsed() / 1000));
}
}, onSuccess, onError);
}
public void reloadData(View view) {
//Setup start of process
mButton.setEnabled(false);
final TimerUtil t = TimerUtil.start();
loadData(t);
}
public static class TimerUtil {
private final long mStartTime;
public TimerUtil(long startTime) {
mStartTime = startTime;
}
public static TimerUtil start() {
return new TimerUtil(System.currentTimeMillis());
}
public long currentElapsed() {
return System.currentTimeMillis() - mStartTime;
}
}
}
package com.test.ui;
导入android.content.Context;
导入android.os.Bundle;
导入android.os.Handler;
导入android.os.Looper;
导入android.support.annotation.NonNull;
导入android.support.annotation.Nullable;
导入android.support.v7.app.AppActivity;
导入android.support.v7.widget.RecyclerView;
导入android.util.Log;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.Button;
导入android.widget.TextView;
导入android.widget.Toast;
导入com.test.R;
导入com.test.model.Attendee;
导入io.realm.OrderedRealmCollection;
导入io.realm.realm;
导入io.realm.RealmAsyncTask;
导入io.realm.realmRecyclServiceAdapter;
导入io.realm.RealmResults;
公共类LoginActivity扩展了AppCompatActivity{
私有静态最终整数记录计数=200000;
私有静态最终整数事务_SIZE=1000;
私有RealmAsyncTask mTask=null;
私人回收商查看Mattendelist;
私有文本视图mCountText;
私人按钮;
私人经办人;
私人领域;
私人地产结果mActualList;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u登录);
mRealm=Realm.getDefaultInstance();
mCountText=(TextView)findViewById(R.id.count\u text);
mButton=(按钮)findviewbyd(R.id.Button);
handler=新处理程序(Looper.getMainLooper());
setCountText((int)mRealm.where(Attendee.class.count());
mActualList=mRealm.where(Attendee.class).lessThan(“年龄”,20.findalsync();
mRealm.executeTransactionAsync(新领域.事务(){
@凌驾
公共void执行(领域){
realm.deleteAll();
setCountText(0);
}
},new Realm.Transaction.OnSuccess(){
@凌驾
成功时的公共无效(){
mButton.setEnabled(真);
}
},新的Realm.Transaction.OnError(){
@凌驾
公共无效onError(可丢弃错误){
String text=“删除错误”;
Log.e(“ANRTEST”、文本、错误);
Toast.makeText(LoginActivity.this,text,Toast.LENGTH_LONG.show();
}
});
}
私有void setCountText(整数大小){
mCountText.setText(String.format(“计数:%s”,大小));
}
@凌驾
受保护的空onDestroy(){
mactualist=null;
如果(mTask!=null&&!mTask.isCancelled()){
mTask.cancel();
mTask=null;
}
if(mRealm!=null&&!mRealm.isClosed()){
mRealm.close();
}
super.ondestory();
}
公共无效载荷数据(最终时间Rutil t){
Realm.Transaction.OnError OnError=新Realm.Transaction.OnError(){
@凌驾
公共无效onError(可丢弃错误){
mTask=null;
Toast.makeText(LoginActivity.this,“现在应该显示已完成”,Toast.LENGTH_LONG.show();
}
};
Realm.Transaction.OnSuccess OnSuccess=新Realm.Transaction.OnSuccess(){
@凌驾
成功时的公共无效(){
mTask=null;
int count=(int)mRealm.where(Attendee.class.count();
如果(计数>=记录计数){
Log.v(“ANRTEST”,String.format(“在%s秒内完成”,t.currentAppeased()/1000));
mButton.setEnabled(false);
}否则{
handler.postDelayed(新的Runnable(){
@凌驾
公开募捐{
载荷数据(t);
}
}, 300);
}
setCountText(计数);
}
};
mTask=mRealm.executeTransactionAsync(新领域.事务(){
@凌驾
公共void执行(领域){
int innerStart=(int)realm.where(Attendee.class.count();
int i=0;
while(i