Activity 尝试访问 SQLite table 时出现空错误

Null error in Activity trying to access SQLite table

新手提问时间又到了; 因此,在 FormActivity 中,我 post 然后从远程服务器上的 SQL table 接收到响应,数据被放入本地 SQLite table行。然后,我有一个包含多个 EditText 字段的片段,我尝试用本地 table 数据填充这些字段。现在,我在 Activity、DrawText() 中有一个方法来执行此操作,但是当 运行 时我遇到了崩溃。我输入的 logcat 消息显示,当调用 DrawText() 时,它从 SQLite table 中提取的值为空。

我已经移动了该方法,试图确保它在已经从服务器响应中填充后访问 table,但无法使其正常工作。任何帮助将不胜感激。下面的代码(现在在帮助下编辑)

FormActivity.java

public class FormActivity extends FragmentActivity {

    //create variables & Logcat tag
    private static final String TAG = FormActivity.class.getSimpleName();
    private EditText inputTitle;
    private EditText inputName;
    private EditText inputSurname;
    private SessionManager sm;
    private SQLiteHandler db;
    private ProgressDialog pDialog;
    private String e_check;
    private String surname;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_form);

        //set inputs for fields
        inputTitle = (EditText) findViewById(R.id.titleText);
        inputName = (EditText) findViewById(R.id.foreText);
        inputSurname = (EditText) findViewById(R.id.surnameText);

        //initialise pager for swipe screens
        ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
        pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));

        // Progress dialog
        pDialog = new ProgressDialog(this);
        pDialog.setCancelable(false);

        //email value passed in
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            e_check = extras.getString("e_check");
        }

        // SQLite database handler - delete old and recreate db from remote server data
        db = new SQLiteHandler(getApplicationContext());

        String email = e_check;
        checkUserDetails(email);
        //<!-- TODO: load db fields to textfields -->
        //<!-- TODO: greeting toast -->
    }
    /**
     * function to verify & retrieve details in mysql db
     * */
    private void checkUserDetails(final String email) {
        // Tag used to cancel the request
        String tag_string_req = "req_retrieve";

        pDialog.setMessage("Retrieving details ...");
        showDialog();

        StringRequest strReq = new StringRequest(Request.Method.POST,
                AppConfig.URL_RETRIEVE, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {
                Log.d(TAG, "Retrieval Response: " + response.toString());
                hideDialog();

                try {
                    JSONObject jObj = new JSONObject(response);
                    boolean error = jObj.getBoolean("error");

                    // Check for error node in json
                    if (!error) {
                        // user exists
                        // fill in textfields
                        String uid = jObj.getString("uid");

                        JSONObject user = jObj.getJSONObject("user");
                        String name = user.getString("name");
                        surname = user.getString("surname");
                        String email = user.getString("email");
                        String created_at = user
                                .getString("created_at");
                        String tel_no = user.getString("tel_no");
                        String home_add = user.getString("home_add");
                        String postcode = user.getString("postcode");
                        String postal = user.getString("postal");

                        // Inserting row in table
                        db.addUser(name, surname, email, uid, created_at, tel_no, home_add, postcode, postal);

                        final Handler handler = new Handler();
                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                //Do something after 300ms
                                DrawText();
                            }
                        }, 300);

                        /* Displaying the user details on the screen
                        FirstFragment fragA = (FirstFragment) getSupportFragmentManager().findFragmentByTag("fragA");
                        fragA.DrawText();*/

                    } else {
                        // Error in login. Get the error message
                        String errorMsg = jObj.getString("error_msg");
                        Toast.makeText(getApplicationContext(),
                                errorMsg, Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
                    // JSON error
                    e.printStackTrace();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Retrieval Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(),
                        error.getMessage(), Toast.LENGTH_LONG).show();
                hideDialog();
            }
        }) {

            @Override
            protected Map<String, String> getParams() {
                // Posting parameters to url
                Map<String, String> params = new HashMap<String, String>();
                params.put("tag", "retrieve");
                params.put("email", email);

                return params;
            }
        };

        // Adding request to request queue
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    public void DrawText() {
        // Fetching user details from sqlite
        HashMap<String, String> user = db.getUserDetails();

        if (user.size() != 0) {
            //String surname = user.get("surname");
            Log.e(TAG, "string surname: " + surname);

            // Displaying the user details on the screen
            inputSurname.setText(surname);
        }else{
            Log.e(TAG, "something you want to say");
        }
    }

    private void showDialog() {
        if (!pDialog.isShowing())
            pDialog.show();
    }

    private void hideDialog() {
        if (pDialog.isShowing())
            pDialog.dismiss();
    }

    private class MyPagerAdapter extends FragmentPagerAdapter {

        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int pos) {
            switch(pos) {

                case 0: return FirstFragment.newInstance("FirstFragment, Instance 1");
                case 1: return SecondFragment.newInstance("SecondFragment, Instance 1");
                case 2: return ThirdFragment.newInstance("ThirdFragment, Instance 1");
                case 3: return FourthFragment.newInstance("FourthFragment, Instance 1");
                //case 4: return FifthFragment.newInstance("ThirdFragment, Instance 3");
                default: return FirstFragment.newInstance("FirstFragment, Default");

            }
        }

        @Override
        // Number of screens we want to swipe between
        public int getCount() {
            return 4;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_form, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Logcat(也已更新)

05-16 09:31:35.560  21981-21981/com.disclosure_scots.disclosure_scots D/FormActivity﹕ Retrieval Response: {"tag":"retrieve","error":false,"uid":"55558b80341dc0.72266271","user":{"name":"John","surname":"Carter","email":"cart@email.com","created_at":"2015-05-15 08:00:32","tel_no":"1231234123","home_add":"22 Lone Road","postcode":"G44 4TT","postal":"false"}}
05-16 09:31:35.643  21981-21981/com.disclosure_scots.disclosure_scots D/SQLiteHandler﹕ Database tables created
05-16 09:31:35.663  21981-21981/com.disclosure_scots.disclosure_scots D/SQLiteHandler﹕ New user inserted into sqlite: 1
05-16 09:31:35.980  21981-21981/com.disclosure_scots.disclosure_scots D/SQLiteHandler﹕ Fetching user from Sqlite: {tel_no=1231234123, postal=false, email=cart@email.com, surname=Carter, name=John, created_at=2015-05-15 08:00:32, uid=55558b80341dc0.72266271, home_add=22 Lone Road, postcode=G44 4TT}
05-16 09:31:35.980  21981-21981/com.disclosure_scots.disclosure_scots E/FormActivity﹕ string surname: Carter
05-16 09:31:35.980  21981-21981/com.disclosure_scots.disclosure_scots D/AndroidRuntime﹕ Shutting down VM
05-16 09:31:35.981  21981-21981/com.disclosure_scots.disclosure_scots E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.disclosure_scots.disclosure_scots, PID: 21981
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.EditText.setText(java.lang.CharSequence)' on a null object reference
            at com.disclosure_scots.disclosure_scots.FormActivity.DrawText(FormActivity.java:180)
            at com.disclosure_scots.disclosure_scots.FormActivity.run(FormActivity.java:125)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5257)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

问题是您试图在添加数据之前收集数据。如您所见,您在收到响应后立即调用 DrawText();(在将数据添加到数据库之前)。很明显,数据将为空。将数据添加到数据库后,您应该调用 DrawText();

db.addUser(name, surname, email, uid, created_at, tel_no, home_add, postcode, postal);
DrawText();

如果上面的代码不起作用,请尝试在 500 毫秒后像这样调用 DrawText()

db.addUser(name, surname, email, uid, created_at, tel_no, home_add, postcode, postal);
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
  @Override
  public void run() {
    //Do something after 500ms
    DrawText();
  }
}, 500);

如果上面没有任何效果。在方法之外声明名称、姓氏等字符串变量(您从 JSON 解析),这将扩展变量从任何方法的可访问性并更新 DrawText();像这样

private String surname;

.....{
    ....
    surname = jsonObject.getString("surname");
    ...
}

public void DrawText() {
        Log.e(TAG, "string surname: " + surname);

        // Displaying the user details on the screen
        inputSurname.setText(surname);
    }
public void DrawText() {
    // Fetching user details from sqlite
    HashMap<String, String> user = db.getUserDetails();
if (user.size() != 0) {
    String surname = user.get("surname");
    Log.e(TAG, "string surname: " + surname);

    // Displaying the user details on the screen
    inputSurname.setText(surname);
}else{
Log.e(TAG, "something you want to say");}

}