This is a Q&A activity where i want to load new question after every 20 seconds, I am loading my data from server using JSON and want to display it in my activity.
After going through lots of SO threads, I found that this can be done using handler. so i implemented the follow code, but now it is giving me NPE on JSONObject while i try to update the UI. How can i achieve my task.
public class Quiz extends ActionBarActivity {
private SessionManager session;
Intent intent;
String categoryid,userid,uri="http://demopurpose.com/Quiz/API/";
JSONArray jArray;
InputStream is;
JSONObject json_data;
int len,countdown=20,lastquestion=0;
private Handler mHandler,handler;
protected static final long TIME_DELAY = 20000;
TextView txtcountdown,txtquestion,txtanswer;
Button btn1,btn2,btn3,btn4;
String opt1,opt2,opt3,opt4,question,answer ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
this.session = new SessionManager(this);
mHandler = new Handler();
handler = new Handler();
txtcountdown =(TextView)findViewById(R.id.txtcountdown);
txtquestion = (TextView)findViewById(R.id.txtquestion);
txtanswer = (TextView)findViewById(R.id.txtanswer);
userid= session.getuserid();
intent =getIntent();
categoryid = intent.getExtras().getString("categoryid");
mHandler.post(refreshActivity);
handler.post(refreshCounter);
}
Runnable refreshActivity=new Runnable(){
Handler handler =new Handler();
public void run() {
countdown =20;
getQuestionurl(userid,categoryid,lastquestion);
lastquestion++;
mHandler.postDelayed(this, TIME_DELAY);
}
};
Runnable refreshCounter = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
countdown--;
txtcountdown.setText(""+countdown);
handler.postDelayed(this, 1000);
}
};
public void getQuestionurl(final String uid, final String cid,final int lastindex){
Thread t = new Thread() {
public void run() {
getquiz(uid,cid,lastindex);
}
};
t.start();
}
public void getquiz(String uid, String cid,int lastindex) {
String result = "";
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(uri+"question.php");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("userId", uid));
nameValuePairs.add(new BasicNameValuePair("categoryId", cid));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}
catch(Exception e){
Log.e("log_tag", "Error in http connection "+e.toString());
}
//convert response to string
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result=sb.toString();
Log.e("result...",result);
jArray = new JSONArray(result);
loadjson(jArray,lastindex);
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
}
private void loadjson(JSONArray arr,int lastindex) {
try{
json_data = arr.getJSONObject(lastindex);
String flag="";
flag =json_data.getString("success");
if(flag.equalsIgnoreCase("0"))
{
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(Quiz.this, "Unable to load Quiz...Try again", Toast.LENGTH_SHORT).show();
}
});
}
else
{
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(Quiz.this, "Loading Quiz...", Toast.LENGTH_SHORT).show();
try{
txtquestion.setText(json_data.getString("title"));
btn1.setText(json_data.getString("option1")); //NPE OCCOURS HERE
btn2.setText(json_data.getString("option2"));
btn3.setText(json_data.getString("option3"));
btn4.setText(json_data.getString("option4"));
}
catch(JSONException je){
je.printStackTrace();
}
}
});
}
}
catch(JSONException je){
je.printStackTrace();
}
}
}
Below is my logcat response. As you can see i am getting the data correctly, but still it gives me NPE.
06-22 17:58:21.417: E/result...(27307): [{"success":"1","questionId":"1","title":"First chief minister","categoryId":"1","option1":"jivraj maheta","option2":"babubhai patel","option3":"narendra modi","option4":"kesubhai patel","answer":"jivraj maheta"},{"success":"1","questionId":"2","title":"test","categoryId":"1","option1":"test","option2":"test","option3":"test","option4":"test","answer":"test"},{"success":"1","questionId":"4","title":"First Chief Minister","categoryId":"1","option1":"jivraj maheta","option2":"babubhai patel","option3":"narendra modi","option4":"kesubhai patel","answer":"jivaraj maheta"},{"success":"1","questionId":"9","title":"Affordable","categoryId":"1","option1":"testt","option2":"fdgfdgf","option3":"fgfdsgdf","option4":"dfhdfh","answer":"3"}]
06-22 17:58:21.427: E/AndroidRuntime(27307): FATAL EXCEPTION: main
06-22 17:58:21.427: E/AndroidRuntime(27307): Process: com.example.knowledgeup, PID: 27307
06-22 17:58:21.427: E/AndroidRuntime(27307): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setText(java.lang.CharSequence)' on a null object reference
06-22 17:58:21.427: E/AndroidRuntime(27307): at com.example.knowledgeup.Quiz$5.run(Quiz.java:163)
06-22 17:58:21.427: E/AndroidRuntime(27307): at android.os.Handler.handleCallback(Handler.java:739)
06-22 17:58:21.427: E/AndroidRuntime(27307): at android.os.Handler.dispatchMessage(Handler.java:95)
06-22 17:58:21.427: E/AndroidRuntime(27307): at android.os.Looper.loop(Looper.java:155)
06-22 17:58:21.427: E/AndroidRuntime(27307): at android.app.ActivityThread.main(ActivityThread.java:5696)
06-22 17:58:21.427: E/AndroidRuntime(27307): at java.lang.reflect.Method.invoke(Native Method)
06-22 17:58:21.427: E/AndroidRuntime(27307): at java.lang.reflect.Method.invoke(Method.java:372)
06-22 17:58:21.427: E/AndroidRuntime(27307): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
06-22 17:58:21.427: E/AndroidRuntime(27307): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
You have to set the variable of btn1 to a concrete view object by using something like
btn1 = findViewById(R.id.my_button_1)