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");}
}
新手提问时间又到了; 因此,在 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");}
}