如何从Realm读取数据

时间:2018-01-11 07:39:02

标签: android realm

我使用Realm开发我的登录应用程序。 我在Realm中写了我的令牌' Config myConfig = mRealm.createObject(Config.class)'。之后从Realm读取没有结果同样Realm没有条目。 我会检查这段代码,我标记为' //检查 - 为什么没有这里的用户'。 而User.size()等于零。

public class MainActivity extends AppCompatActivity {

    private Realm mRealm;
    private Realm mRealmInstance;

    Button btnLogin;

    public void onLogin() {

        AsyncHttpClient client = new AsyncHttpClient();

        RequestParams rp = new RequestParams();
        rp.add("email", "name@example.com");
        rp.add("password", "159753");

        RequestHandle post = client.post("https://example.com/api/v1/auth", rp, new JsonHttpResponseHandler() {

            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                // Root JSON in response is an dictionary i.e { "data : [ ... ] }
                // Handle resulting parsed JSON response here
                try {
                    String tokenString = response.getString("token");

                    mRealm.beginTransaction();
                    Config myConfig = mRealm.createObject(Config.class);
                    myConfig.name = "token";
                    myConfig.tokenValue = tokenString;
                    mRealm.commitTransaction();
                } catch (NullPointerException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, String res, Throwable t) {
                // called when response HTTP status is "4XX" (eg. 401, 403, 404)
            }
        });

        //check - why no users here
        TextView tvHello = (TextView)findViewById(R.id.tvHello);
        try {
            RealmResults User = mRealmInstance.where(Config.class).equalTo("name", "token").findAllAsync();
            if (User.size() > 0) {

                String nameOfUser = User.get(0).toString();
                tvHello.setText(nameOfUser);

            } else if (User.size() == 0) {
                Log.e("query","query size is "+User.size());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //end of test block
    }

3 个答案:

答案 0 :(得分:2)

您在访问数据之前正在进行异步网络呼叫。网络呼叫尚未完成,因此您的数据为空。将您的数据访问代码放在onSuccess()回调中。

public class MainActivity extends AppCompatActivity {

...

public void onLogin() {

    ...

    RequestHandle post = client.post(
        "https://example.com/api/v1/auth", 
        rp, 
        new JsonHttpResponseHandler() {

        @Override
        public void onSuccess(
            int statusCode, 
            Header[] headers, 
            JSONObject response) {
            try {
                String tokenString = response.getString("token");

                mRealm.beginTransaction();
                Config myConfig = mRealm.createObject(Config.class);
                myConfig.name = "token";
                myConfig.tokenValue = tokenString;
                mRealm.commitTransaction();

                populateData();
            } catch (NullPointerException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(
            int statusCode,
            Header[] headers, 
            String res, 
            Throwable t) {
            // called when response HTTP status is "4XX" (eg. 401, 403, 404)
        }
    });
}

private void populateData() {
    TextView tvHello = (TextView)findViewById(R.id.tvHello);
    try {
        RealmResults User = 
            mRealmInstance.where(Config.class).equalTo("name", "token").findAll();
        if (User.size() > 0) {

            String nameOfUser = User.get(0).toString();
            tvHello.setText(nameOfUser);

        } else if (User.size() == 0) {
            Log.e("query","query size is "+User.size());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

另请注意,您应使用findAll()代替findAllAsync()。阅读文档以获取有关差异的更多信息:https://realm.io/blog/realm-java-0-84-0/

答案 1 :(得分:1)

这是因为client.post(...将在另一个线程中执行。只有在该任务完成后,才会在UI线程中执行onSuccess()//check - why no users here之后的代码在执行onSuccess()之前或之后执行。这就是User.size()等于零的原因。修改代码以使其正常工作

public class MainActivity extends AppCompatActivity {

    private Realm mRealm;
    private Realm mRealmInstance;
    private TextView tvHello;

    Button btnLogin;

    public void onLogin() {

        tvHello = (TextView) findViewById(R.id.tvHello);
        AsyncHttpClient client = new AsyncHttpClient();

        RequestParams rp = new RequestParams();
        rp.add("email", "name@example.com");
        rp.add("password", "159753");

        RequestHandle post = client.post("https://example.com/api/v1/auth", rp, new JsonHttpResponseHandler() {

            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                // Root JSON in response is an dictionary i.e { "data : [ ... ] }
                // Handle resulting parsed JSON response here
                try {
                    String tokenString = response.getString("token");

                    mRealm.beginTransaction();
                    Config myConfig = mRealm.createObject(Config.class);
                    myConfig.name = "token";
                    myConfig.tokenValue = tokenString;
                    mRealm.commitTransaction();

                    RealmResults User = mRealmInstance.where(Config.class).equalTo("name", "token").findAllAsync();
                    if (User.size() > 0) {

                        String nameOfUser = User.get(0).toString();
                        tvHello.setText(nameOfUser);

                    } else if (User.size() == 0) {
                        Log.e("query", "query size is " + User.size());
                    }
                } catch (NullPointerException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, String res, Throwable t) {
                // called when response HTTP status is "4XX" (eg. 401, 403, 404)
            }
        });
    }
}

答案 2 :(得分:1)

要在从后台线程写入Realm时接收通知,您应该使用RealmChangeListener(并将RealmResults保留为字段)。

public class MainActivity extends AppCompatActivity {

    private Realm realm;

    Button btnLogin;

    private RealmResults<Config> userResults;
    private RealmChangeListener<RealmResults<Config>> changeListener = new RealmChangeListener<RealmResults<Config>>() {
        @Override
        public void onChange(RealmResults<Config> element) {
            TextView tvHello = (TextView)findViewById(R.id.tvHello);
            try {
                if (element.size() > 0) {        
                    String nameOfUser = element.get(0).toString();
                    tvHello.setText(nameOfUser);        
                } else if (element.size() == 0) {
                    Log.e("query","query size is "+element.size());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(..);
        realm = Realm.getDefaultInstance();
        userResults = realm.where(Config.class).equalTo("name", "token").findAllAsync();
        userResults.addChangeListener(changeListener);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        userResults.removeAllChangeListeners();
        userResults = null;
        realm.close();
        realm = null;
    }

    public void onLogin() {

        AsyncHttpClient client = new AsyncHttpClient();

        RequestParams rp = new RequestParams();
        rp.add("email", "name@example.com");
        rp.add("password", "159753");

        RequestHandle post = client.post("https://example.com/api/v1/auth", rp, new JsonHttpResponseHandler() {

            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                // Root JSON in response is an dictionary i.e { "data : [ ... ] }
                // Handle resulting parsed JSON response here
                try {
                    String tokenString = response.getString("token");

                    try(Realm r = Realm.getDefaultInstance()) {
                        r.executeTransaction(new Realm.Transaction() {
                            @Override
                            public void execute(Realm realm) {
                                Config myConfig = realm.createObject(Config.class);
                                myConfig.name = "token";
                                myConfig.tokenValue = tokenString;
                            }
                        });
                    }
                } catch (NullPointerException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, String res, Throwable t) {
                // called when response HTTP status is "4XX" (eg. 401, 403, 404)
            }
        });

        //end of test block
    }