A / libc:致命信号11(SIGSEGV),代码1 Realm Android

时间:2017-07-25 07:45:52

标签: java android android-recyclerview realm realm-mobile-platform

我正在尝试在Android中测试领域还原和备份功能。我正在关注文章here。我正在使用Realm github的示例recyclerview代码link

我能够成功备份。但是,如果我恢复备份然后尝试打开活动(RecyclerViewExampleActivity.java),它与领域恢复的数据库交互以填充recyclerview,应用程序崩溃,当我重新启动应用程序然后再次启动recyclerview活动它恢复工作正常db,崩溃时抛出以下异常:

07-25 12:52:18.262 1531-1627/io.realm.examples.adapters A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x4 in tid 1627 (amples.adapters)

                                                                [ 07-25 12:52:18.263   441:  441 W/         ]
                                                                debuggerd: handling request: pid=1531 uid=10157 gid=10157 tid=1627

以下是应用的代码 -

MyApplication.java

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        Realm.init(this);
        RealmConfiguration realmConfig = new RealmConfiguration.Builder()
                .initialData(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        realm.createObject(Parent.class);
                    }})
                .build();
        Realm.setDefaultConfiguration(realmConfig);
    }

MainActivity.java

public class MainActivity extends AppCompatActivity {
Button btnbackup,btnrest;
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    setupButton(R.id.button_listview, ListViewExampleActivity.class);
    setupButton(R.id.button_recyclerview, RecyclerViewExampleActivity.class);

    checkStoragePermissions(this);

    btnbackup=(Button) findViewById(R.id.button_backup);
    btnrest=(Button) findViewById(R.id.button_restore);

    btnrest.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            System.out.println("restore clicked");
            RealmBackupRestore rel = new RealmBackupRestore(MainActivity.this);
            rel.restore();
        }
    });

    btnbackup.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            System.out.println("backup clicked");
            RealmBackupRestore rel = new RealmBackupRestore(MainActivity.this);
            rel.backup();
        }
    });
}

void startActivity(Class<? extends Activity> activityClass) {
    startActivity(new Intent(this, activityClass));
}

private void setupButton(int id, final Class<? extends Activity> activityClass) {
    findViewById(id).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(activityClass);
        }
    });
}

private void checkStoragePermissions(Activity activity) {
    // Check if we have write permission
    int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

    if(permission != PackageManager.PERMISSION_GRANTED){
        ActivityCompat.requestPermissions(
                activity,
                PERMISSIONS_STORAGE,
                REQUEST_EXTERNAL_STORAGE
        );
    }
}
}

RecyclerViewExampleActivity.java

public class RecyclerViewExampleActivity extends AppCompatActivity {

private Realm realm;
private RecyclerView recyclerView;
private Menu menu;
private MyRecyclerViewAdapter adapter;

private class TouchHelperCallback extends ItemTouchHelper.SimpleCallback {

    TouchHelperCallback() {
        super(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return true;
    }

    @Override
    public void onSwiped(final RecyclerView.ViewHolder viewHolder, int direction) {
        DataHelper.deleteItemAsync(realm, viewHolder.getItemId());
    }

    @Override
    public boolean isLongPressDragEnabled() {
        return true;
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_recyclerview);
    realm = Realm.getDefaultInstance();
    recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    setUpRecyclerView();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    recyclerView.setAdapter(null);
    realm.close();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    this.menu = menu;
    getMenuInflater().inflate(R.menu.listview_options, menu);
    menu.setGroupVisible(R.id.group_normal_mode, true);
    menu.setGroupVisible(R.id.group_delete_mode, false);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    switch(id) {
        case R.id.action_add:
            DataHelper.addItemAsync(realm);
            return true;
        case R.id.action_random:
            DataHelper.randomAddItemAsync(realm);
            return true;
        case R.id.action_start_delete_mode:
            adapter.enableDeletionMode(true);
            menu.setGroupVisible(R.id.group_normal_mode, false);
            menu.setGroupVisible(R.id.group_delete_mode, true);
            return true;
        case R.id.action_end_delete_mode:
            DataHelper.deleteItemsAsync(realm, adapter.getCountersToDelete());
            // Fall through
        case R.id.action_cancel_delete_mode:
            adapter.enableDeletionMode(false);
            menu.setGroupVisible(R.id.group_normal_mode, true);
            menu.setGroupVisible(R.id.group_delete_mode, false);
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

private void setUpRecyclerView() {
    if(realm==null)
        realm=Realm.getDefaultInstance();

    adapter = new MyRecyclerViewAdapter(realm.where(Parent.class).findFirst().getCounterList());
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(adapter);
    recyclerView.setHasFixedSize(true);
    recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));

    TouchHelperCallback touchHelperCallback = new TouchHelperCallback();
    ItemTouchHelper touchHelper = new ItemTouchHelper(touchHelperCallback);
    touchHelper.attachToRecyclerView(recyclerView);
}

}

RecyclerViewAdapter.java

class MyRecyclerViewAdapter extends RealmRecyclerViewAdapter<Counter, MyRecyclerViewAdapter.MyViewHolder> {

private boolean inDeletionMode = false;
private Set<Integer> countersToDelete = new HashSet<Integer>();

MyRecyclerViewAdapter(OrderedRealmCollection<Counter> data) {
    super(data, true);
    setHasStableIds(true);
}

void enableDeletionMode(boolean enabled) {
    inDeletionMode = enabled;
    if (!enabled) {
        countersToDelete.clear();
    }
    notifyDataSetChanged();
}

Set<Integer> getCountersToDelete() {
    return countersToDelete;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.row, parent, false);
    return new MyViewHolder(itemView);
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    final Counter obj = getItem(position);
    holder.data = obj;
    //noinspection ConstantConditions
    holder.title.setText(obj.getCountString());
    holder.deletedCheckBox.setChecked(countersToDelete.contains(obj.getCount()));
    if (inDeletionMode) {
        holder.deletedCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    countersToDelete.add(obj.getCount());
                } else {
                    countersToDelete.remove(obj.getCount());
                }
            }
        });
    } else {
        holder.deletedCheckBox.setOnCheckedChangeListener(null);
    }
    holder.deletedCheckBox.setVisibility(inDeletionMode ? View.VISIBLE : View.GONE);
}

@Override
public long getItemId(int index) {
    //noinspection ConstantConditions
    return getItem(index).getCount();
}

class MyViewHolder extends RecyclerView.ViewHolder {
    TextView title;
    CheckBox deletedCheckBox;
    public Counter data;

    MyViewHolder(View view) {
        super(view);
        title = (TextView) view.findViewById(R.id.textview);
        deletedCheckBox = (CheckBox) view.findViewById(R.id.checkBox);
    }
}
}

Counter.java

public class Counter extends RealmObject {
    public static final String FIELD_COUNT = "count";

    private static AtomicInteger INTEGER_COUNTER = new AtomicInteger(0);

    @PrimaryKey
    private int count;

    public int getCount() {
        return count;
    }

    public String getCountString() {
        return Integer.toString(count);
    }

    //  create() & delete() needs to be called inside a transaction.
    static void create(Realm realm) {
        create(realm, false);
    }

    static void create(Realm realm, boolean randomlyInsert) {
        Parent parent = realm.where(Parent.class).findFirst();
        RealmList<Counter> counters = parent.getCounterList();
        Counter counter = realm.createObject(Counter.class, increment());
        if (randomlyInsert && counters.size() > 0) {
            Random rand = new Random();
            counters.listIterator(rand.nextInt(counters.size())).add(counter);
        } else {
            counters.add(counter);
        }
    }

    static void delete(Realm realm, long id) {
        Counter counter = realm.where(Counter.class).equalTo(FIELD_COUNT, id).findFirst();
        // Otherwise it has been deleted already.
        if (counter != null) {
            counter.deleteFromRealm();
        }
    }

    private static int increment() {
        return INTEGER_COUNTER.getAndIncrement();
    }
}

Datahelper.java

public class DataHelper {

    // Create 3 counters and insert them into random place of the list.
    public static void randomAddItemAsync(Realm realm) {
        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                for (int i = 0; i < 3; i++) {
                    Counter.create(realm, true);
                }
            }
        });
    }

    public static void addItemAsync(Realm realm) {
        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                Counter.create(realm);
            }
        });
    }

    public static void deleteItemAsync(Realm realm, final long id) {
        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                Counter.delete(realm, id);
            }
        });
    }

    public static void deleteItemsAsync(Realm realm, Collection<Integer> ids) {
        // Create an new array to avoid concurrency problem.
        final Integer[] idsToDelete = new Integer[ids.size()];
        ids.toArray(idsToDelete);
        realm.executeTransactionAsync(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                for (Integer id : idsToDelete) {
                    Counter.delete(realm, id);
                }
            }
        });
    }
}

Parent.java

public class Parent extends RealmObject {
    @SuppressWarnings("unused")
    private RealmList<Counter> counterList;

    public RealmList<Counter> getCounterList() {
        return counterList;
    }
}

的AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
    android:name=".MyApplication"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">

    <activity
        android:name="io.realm.examples.adapters.MainActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
    <activity
        android:name=".ui.listview.ListViewExampleActivity"
        android:label="ListView Example"/>
    <activity
        android:name=".ui.recyclerview.RecyclerViewExampleActivity"
        android:label="RecyclerView Example"/>
</application>

</manifest>

Gradle App

apply plugin: 'com.android.application'
apply plugin: 'android-command'
apply plugin: 'realm-android'

android {
    compileSdkVersion sdkVersion
    buildToolsVersion buildTools

    defaultConfig {
        applicationId "io.realm.examples.adapters"
        minSdkVersion 15
        targetSdkVersion sdkVersion
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
        }
    }
    command {
        events 2000
    }
    repositories {
        jcenter()
        mavenCentral()
        maven { url 'https://github.com/uPhyca/stetho-realm/raw/master/maven-repo' }
    }
}

dependencies {
    compile project(':adapters')
    compile "com.android.support:appcompat-v7:${supportLibraryVersion}"
    compile "com.android.support:recyclerview-v7:${supportLibraryVersion}"
    compile 'com.uphyca:stetho_realm:2.0.0'
    compile 'com.facebook.stetho:stetho:1.5.0'

}

有人可以帮忙弄清楚为什么异常会从何而来?为什么不重新启动app重启?有没有资源我可以得到更好的Realm db备份/恢复示例,这不会让应用程序崩溃?感谢。

在更多的测试中,我注意到应用程序有时会在执行还原后立即崩溃,代码2错误而不是1,如上所述,错误显示如下:

07-25 13:36:12.318 17784-18482/io.realm.examples.adapters A/libc: Fatal signal 11 (SIGSEGV), code 2, fault addr 0xaa8ea000 in tid 18482 (StethoWorker-ma)

                                                                  [ 07-25 13:36:12.319   441:  441 W/         ]
                                                                  debuggerd: handling request: pid=17784 uid=10160 gid=10160 tid=18482

0 个答案:

没有答案