iam trying to build an android app which makes users to do some calculation in a time limit. The code worked well until i divided the code into two parts and created another class for doing other task .
I have imported all the corressponding packages and class files to the new class .There were no errors in the code but when i run the app it crashes .I tried changing the code many times but no use. Code works well when i combine all the code into a single class.
the error i get is "java.lang.StackOverflowError: stack size 8MB on line number "
**MainActivity.java**
package e.nani.firstattempt;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Vibrator;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
public int a1;//random num 1
public int a2;//random num 2;
public TextView textview;
public Button b1;
public Button b2;
public Button b3;
public Button b4;
public int option1;
public int option2;
public int option3;
public int option4;
public int score=0;
TextView scoreid;
int numberofquestions=10;
TextView time;
public int answers[]=new int[4];
Logic c=new Logic();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textview=(TextView)findViewById(R.id.sum);
b1=(Button)findViewById(R.id.option1);
b2=(Button)findViewById(R.id.option2);
b3=(Button)findViewById(R.id.option3);
b4=(Button)findViewById(R.id.option4);
time=(TextView)findViewById(R.id.timer);
scoreid=(TextView)findViewById(R.id.scoreid) ;
scoreid.setText((0+"/"+numberofquestions));
c.operatio();
timer.start();
}
public void operation(View V)
{
try{
switch(V.getId()) {
case R.id.option1:
if (b1.getText().equals(Integer.toString(option4))) {
score = score + 1;
c.operatio();
scoreid.setText((score +"/"+ numberofquestions));
} else {
Toast.makeText(this, "wrong answer", Toast.LENGTH_SHORT).show();
Vibrator vibrator=(Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(500);
c.operatio();
}
break;
case R.id.option2:
if (b2.getText().equals(Integer.toString(option4))) {
score = score + 1;
c.operatio();
scoreid.setText(score+"/"+ numberofquestions);
} else
{
Toast.makeText(this, "wrong answer", Toast.LENGTH_SHORT).show();
Vibrator vibrator=(Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(500);
c.operatio();
}
break;
case R.id.option3:
if (b3.getText().equals(Integer.toString(option4))) {
score = score + 1;
c.operatio();
scoreid.setText((score+"/"+ numberofquestions));
} else
{
Toast.makeText(this, "wrong answer", Toast.LENGTH_SHORT).show();
Vibrator vibrator=(Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(500);
c.operatio();
}
break;
case R.id.option4:
if (b4.getText().equals(Integer.toString(option4))) {
score = score + 1;
c.operatio();
scoreid.setText(score+"/"+ numberofquestions);
} else
{
Toast.makeText(this, "wrong answer", Toast.LENGTH_SHORT).show();
Vibrator vibrator=(Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(500);
c.operatio();
}
break;
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
CountDownTimer timer=new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
time.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
time.setText("done!");
}
};
}
Logic.java
package e.nani.firstattempt;
import java.util.Random;
class Logic {
MainActivity s=new MainActivity();
public void operatio() {
try {
Random n = new Random();
int n1 = n.nextInt(4);
int n2 = n.nextInt(4);
int n3 = n.nextInt(4);
int n4 = n.nextInt(4);
s.a1 = n.nextInt(51);
s.a2 = n.nextInt(35);
s.option1 = n.nextInt((s.a1 + s.a2) + 1);
s.option2 = n.nextInt((s.a1 + s.a2) + 1);
s.option3 = n.nextInt((s.a1 + s.a2) + 1);
s.option4 = s.a1 + s.a2;
s.answers[n1] = s.option1;
while (n2 == n1) {
n2 = n.nextInt(4);
}
while (s.option2 == s.option1 || s.option2 == s.option4) {
s.option2 = n.nextInt((s.a1 + s.a2) + 1);
}
s.answers[n2] = s.option2;
while (s.option3 == s.option2 || s.option3 == s.option1 || s.option3 == s.option4)
{
s.option3 = n.nextInt((s.a1 + s.a2) + 1);
}
while (n3 == n2 || n3 == n1)
{
n3 = n.nextInt(4);
}
s.answers[n3] = s.option3;
while (n4 == n2 || n4 == n1 || n4 == n3) {
n4 = n.nextInt(4);
}
s.answers[n4] = s.option4;
s.b1.setText(Integer.toString(s.answers[0]));
s.b2.setText(Integer.toString(s.answers[1]));
s.b3.setText(Integer.toString(s.answers[2]));
s.b4.setText(Integer.toString(s.answers[3]));
s.textview.setText(s.a1 + "+" + s.a2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
The main question here is ,why is the app working fine when the code is only in main class but not working when some code is written in other class ?
ThankYou.
In your MainActivity you have a variable c with type Logic which is instantiated.
But in your Logic class has MainActivity type variable which try to instantiate MainActivity class. In a nutshell in a class A you instantiate class B which instatieates class A and so on...
By the way you cannot instantiate AppCompatActivity classes directly.
So remove MainActivity s=new MainActivity(); in your Logic.class.
Hope I could help you.
Related
Making a simple BrainTrain app, the updateAnswer method gives out random answers to the question but the issue comes up whenever i call the optionsPressed method and try getting any of the object, the arrayList gives out IndexOutOfBoundsException.
package com.example.nishantsaini.braintrain;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.CountDownTimer;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Random;
import static android.R.color.black;
import static android.R.color.holo_blue_bright;
import static android.R.color.holo_blue_dark;
import static android.R.color.holo_blue_light;
import static android.R.color.holo_green_light;
public class MainActivity extends AppCompatActivity {
Random rnd = new Random();
boolean gameisActive = false;
int count = 0;
CountDownTimer cd;
int var1,var2;
ArrayList<Button> options;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cd = new CountDownTimer(30000, 1000) {
#Override
public void onTick(long l) {
Log.i("Time Left:", Long.toString(l / 1000));
TextView timer = (TextView) findViewById(R.id.timer);
timer.setText("0:" + String.format("%02d", (l / 1000)));
}
#Override
public void onFinish() {
TextView score = (TextView) findViewById(R.id.Score);
LinearLayout onFinishLayout = (LinearLayout) findViewById(R.id.onFinishLayout);
/*score.setText( "You got " + getScore() + "right!");
*/
}
};
options = new ArrayList<>();
options.add((Button) findViewById(R.id.option2));
options.add((Button) findViewById(R.id.option1));
options.add((Button) findViewById(R.id.option3));
options.add((Button) findViewById(R.id.option4));
}
public void start(View view) {
cd.start();
Button start = (Button) findViewById(R.id.start);
updateQuestion();
updateAnswers(options);
start.setText("Replay");
}
public void optionPressed(View view){
ColorDrawable blue_d = new ColorDrawable(getResources().getColor(R.color.blue_b));
ColorDrawable blue_l = new ColorDrawable(getResources().getColor(R.color.blue_l));
ColorDrawable blue_b = new ColorDrawable(getResources().getColor(R.color.blue_b));
ColorDrawable green = new ColorDrawable(getResources().getColor(R.color.green));
Drawable color = blue_b;
while(options.size() > 0) {
int index = rnd.nextInt(options.size());
Button b = options.get(index);
if (color == blue_b){
color = blue_d;
b.setBackground(color);
}
else if (color == blue_d){
color = green;
b.setBackground(color);
}
else if (color == green){
color = blue_l;
b.setBackground(color);
}
else if (color == blue_l)
{
color = blue_b;
b.setBackground(color);
}
options.remove(index);
}
updateQuestion();
updateScore();
updateAnswers(options);
}
public void updateQuestion(){
var1 = 5 + (int)(Math.random()*20);
var2 = 5 + (int)(Math.random()*20);
TextView question = (TextView) findViewById(R.id.question);
question.setText(Integer.toString(var1) +" + " + Integer.toString(var2) + " = ");
question.setPadding(0,50,0,0);
}
public void updateScore(){
count++;
int correct = 0;
TextView score = (TextView) findViewById(R.id.points);
score.setText(Integer.toString(correct) + "/" + Integer.toString(count));
}
public void updateAnswers(ArrayList<Button> arrayList ){
Button b;
int answer = var1 + var2;
int indexAtWhichRealAnswerGoes = 1+ (int) (Math.random()*3);
int id ;
Log.i("arraylist size",Integer.toString(options.size()));
b = arrayList.get(indexAtWhichRealAnswerGoes);
b.setText(Integer.toString(answer));
id = b.getId();
arrayList.remove(indexAtWhichRealAnswerGoes);
for (int i = 0; i < arrayList.size(); i++) {
int randomanswer = (answer-7) + (int)(Math.random()*(answer+7));
b = arrayList.get(i);
b.setText(Integer.toString(randomanswer));
}
arrayList.add((Button) findViewById(id));
Log.i("arraylist size",Integer.toString(arrayList.size()));
}
}
So, you call updateAnswers(options); using the list that you previously emptied
while(options.size() > 0) {
int index = rnd.nextInt(options.size());
...
options.remove(index);
}
...
updateAnswers(options);
At that point, the list is empty.
In the method, you safely used for (int i = 0; i < arrayList.size(); i++) { to prevent any error but before that we see
int indexAtWhichRealAnswerGoes = 1+ (int) (Math.random()*3);
...
b = arrayList.get(indexAtWhichRealAnswerGoes);
You get that random index without checking the size of the list. (List that is empty at that point).
If you want to keep the list with its value, but the logic can't be change so the remove is necessary, you need to do a copy of the list to work on that one, and pass the original to the method updateAnswers.
List<Button> copyOptions = new ArrayList<>(options);
It will share the same instance, but you can update the list copyOptions without having any impact on options
I am developing a quiz application,and im facing with a issue with back and next button. Here is the situation:
I have 40 questions in total,and in the java class of quiz i initialize an integer rowID=1
W
hen I'm at the first position the button is disabled, but when I press next still it stays disabled, the same thing for next button
I have a TextView which shows the number of current question, and if I'm at the question number 40 and I press next again, it goes 41. it shouldn't go
Here is my code:
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.shawnlin.numberpicker.NumberPicker;
import org.json.JSONObject;
import java.util.List;
import java.util.concurrent.TimeUnit;
import retrofit2.Call;
import retrofit2.Callback;
import static autoshkolla.almotech.org.autoshkollastudenti.R.id.testi;
public class Activity_Quiz extends AppCompatActivity {
SaveData saveData;
String ApiKey;
Dialog dialog;
Gson gson;
Button next_question, previous_question;
int quizID, questionID, trueanswer, useranswer;
int rowID = 1;
String question, filename, mime, image;
SQLiteDatabase db;
TextView viewquestion, question_number, user_email, user_id, quiz_number;
QuizAdapter quizAdapter;
private AllLectureAdapter adapter;
DbProductModel dbProductModel;
List < Quiz_Data > lecture;
RadioGroup my_answer;
NumberPicker numberPicker;
Button start_timer, stop_timer;
MyCountDownTimer myCountDownTimer;
TextView koha;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity__quiz);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(false);
getSupportActionBar().setTitle(Html.fromHtml("<font color='#FFFFFF'><b>QUIZ</b></font>"));
saveData = new SaveData(getApplication());
gson = new GsonBuilder().create();
ApiKey = "bearer " + saveData.getAutoUserToken();
if (!saveData.getQuizStatus().equalsIgnoreCase("start")) {
myCountDownTimer = new MyCountDownTimer(2400000, 1000);
myCountDownTimer.start();
loading();
generate_quiz(ApiKey);
saveData.setQuizStatus("in_progress");
}
question_number = (TextView) findViewById(R.id.questionnumber);
user_email = (TextView) findViewById(R.id.email);
user_id = (TextView) findViewById(R.id.ID);
quiz_number = (TextView) findViewById(testi);
user_email.setText("Email : " + saveData.getAutoUserEmail());
user_id.setText("ID : " + saveData.getAutoUserId() + "");
next_question = (Button) findViewById(R.id.nextbtn);
previous_question = (Button) findViewById(R.id.prevbtn);
viewquestion = (TextView) findViewById(R.id.question);
my_answer = (RadioGroup) findViewById(R.id.useranswer);
final QuizSendModel results = new QuizSendModel();
koha = (TextView) findViewById(R.id.time);
if (rowID > 1 && rowID < 40) {
previous_question.setEnabled(true);
next_question.setEnabled(true);
} else if (rowID == 40) {
next_question.setEnabled(false);
} else if (rowID == 1) {
previous_question.setEnabled(false);
}
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.gotoquestion);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final Dialog dialog = new Dialog(Activity_Quiz.this);
dialog.setContentView(R.layout.questions);
dialog.setCancelable(true);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
Button shiko = (Button) dialog.findViewById(R.id.shikopyetje);
numberPicker = (NumberPicker) dialog.findViewById(R.id.number_picker);
dialog.show();
/* Window window = dialog.getWindow();
window.setLayout(400, 600);*/
shiko.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
question_number.setText(String.valueOf(numberPicker.getValue()) + "/40");
String[] proj = {
UsersProvider.QUESTION,
UsersProvider.USER_ANSWER
};
String[] args = {
String.valueOf(numberPicker.getValue())
};
Cursor c = getContentResolver().query(UsersProvider.CONTENT_URI, proj, UsersProvider.ID_ROW + " = ?", args, null);
if (c.moveToFirst()) {
do {
viewquestion.setText(c.getString(c.getColumnIndex(UsersProvider.QUESTION)));
String uswanswradio = c.getString(c.getColumnIndex(UsersProvider.USER_ANSWER));
if (uswanswradio == null) {
my_answer.clearCheck();
} else if (uswanswradio.equalsIgnoreCase("0")) {
my_answer.check(R.id.radioJO);
} else if (uswanswradio.equalsIgnoreCase("1")) {
my_answer.check(R.id.radioPO);
}
} while (c.moveToNext());
}
dialog.dismiss();
}
});
}
});
viewquestion.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Cursor c = getContentResolver().query(UsersProvider.CONTENT_URI, null, null, null, null);
if (c.moveToFirst()) {
do {
/*Toast.makeText(getApplicationContext()," "+c.getString(c.getColumnIndex(UsersProvider.NAME))+", "+c.getString(c.getColumnIndex(UsersProvider.ADDRESS)),Toast.LENGTH_LONG).show();
System.out.println("emri : "+c.getString(c.getColumnIndex(UsersProvider.NAME))+" address : "+c.getString(c.getColumnIndex(UsersProvider.ADDRESS)));*/
results.setId_question(c.getString(c.getColumnIndex(UsersProvider.ID_QUESTION)));
results.setUser_answer(c.getString(c.getColumnIndex(UsersProvider.USER_ANSWER)));
System.out.println("pyetja : " + results.getId_question());
System.out.println("uans : " + results.getUser_answer());
} while (c.moveToNext());
}
}
});
my_answer.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
public void onCheckedChanged(RadioGroup group,
int checkedId) {
if (checkedId == R.id.radioPO) {
useranswer = 1;
} else if (checkedId == R.id.radioJO) {
useranswer = 0;
}
ContentValues values = new ContentValues();
values.put(UsersProvider.USER_ANSWER, useranswer);
String row = String.valueOf(rowID);
String[] whereArgs = {
row
};
getContentResolver().update(UsersProvider.CONTENT_URI, values, UsersProvider.ID_ROW + " =? ", whereArgs);
}
});
previous_question.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rowID = rowID - 1;
question_number.setText(rowID + "/40");
String[] proj = {
UsersProvider.QUESTION,
UsersProvider.USER_ANSWER
};
String[] args = {
String.valueOf(rowID)
};
Cursor c = getContentResolver().query(UsersProvider.CONTENT_URI, proj, UsersProvider.ID_ROW + " = ?", args, null);
if (c.moveToFirst()) {
do {
viewquestion.setText(c.getString(c.getColumnIndex(UsersProvider.QUESTION)));
String uswanswradio = c.getString(c.getColumnIndex(UsersProvider.USER_ANSWER));
System.out.println("pergjigjeeuserit : " + c.getString(c.getColumnIndex(UsersProvider.USER_ANSWER)));
if (uswanswradio == null) {
my_answer.clearCheck();
} else if (uswanswradio.equalsIgnoreCase("0")) {
my_answer.check(R.id.radioJO);
} else if (uswanswradio.equalsIgnoreCase("1")) {
my_answer.check(R.id.radioPO);
}
} while (c.moveToNext());
}
}
});
next_question.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
my_answer.clearCheck();
rowID = rowID + 1;
question_number.setText(rowID + "/40");
String[] proj = {
UsersProvider.QUESTION,
UsersProvider.USER_ANSWER
};
String[] args = {
String.valueOf(rowID)
};
Cursor c = getContentResolver().query(UsersProvider.CONTENT_URI, proj, UsersProvider.ID_ROW + " = ?", args, null);
if (c.moveToFirst()) {
do {
viewquestion.setText(c.getString(c.getColumnIndex(UsersProvider.QUESTION)));
String uswanswradio = c.getString(c.getColumnIndex(UsersProvider.USER_ANSWER));
if (uswanswradio == null) {
my_answer.clearCheck();
} else if (uswanswradio.equalsIgnoreCase("0")) {
my_answer.check(R.id.radioJO);
} else if (uswanswradio.equalsIgnoreCase("1")) {
my_answer.check(R.id.radioPO);
}
} while (c.moveToNext());
}
}
});
String[] proj = {
UsersProvider.QUESTION
};
String[] args = {
String.valueOf(1)
};
Cursor c = getContentResolver().query(UsersProvider.CONTENT_URI, proj, UsersProvider.ID_ROW + " = ?", args, null);
if (c.moveToFirst()) {
do {
rowID = 1;
viewquestion.setText(c.getString(c.getColumnIndex(UsersProvider.QUESTION)));
} while (c.moveToNext());
}
}
public void generate_quiz(String APIKEY) {
API api = APIClient.getApi(APIKEY);
Call < Quiz > totclient = api.quiz();
totclient.enqueue(new Callback < Quiz > () {
#Override
public void onResponse(Call < Quiz > call, retrofit2.Response < Quiz > response) {
dialog.dismiss();
// Log.d(TAG, "Succes:" + response.body().isError());
JSONObject obj = new JSONObject();
System.out.println("AllLectures:" + gson.toJson(response.body()));
System.out.println("quiz id:" + gson.toJson(response.body().getQuizNumber()));
quiz_number.setText("Testi : " + gson.toJson(response.body().getQuizNumber()));
if (!gson.toJson(response.body()).equalsIgnoreCase("null")) {
if (gson.toJson(response.body().getError()).equalsIgnoreCase("false")) {
ContentValues values = new ContentValues();
getContentResolver().delete(UsersProvider.CONTENT_URI, null, null);
lecture = response.body().getData();
final List < Quiz_Data > movies = response.body().getData();
for (int i = 0; i < movies.size(); i++) {
quizID = response.body().getQuizNumber();
questionID = response.body().getData().get(i).getId();
question = response.body().getData().get(i).getQuestion();
trueanswer = response.body().getData().get(i).getTrueAnswer();
filename = response.body().getData().get(i).getOriginalFilename();
mime = response.body().getData().get(i).getMime();
image = response.body().getData().get(i).getImage();
values.put(UsersProvider.QUESTION, question);
values.put(UsersProvider.ID_ROW, i + 1);
values.put(UsersProvider.ID_QUESTION, questionID);
values.put(UsersProvider.TRUE_ANSWER, trueanswer);
// values.put(UsersProvider.USER_ANSWER,-1);
values.put(UsersProvider.ORIGINAL_FILENAME, filename);
values.put(UsersProvider.MIME, mime);
values.put(UsersProvider.IMAGE, image);
Uri uri = getContentResolver().insert(UsersProvider.CONTENT_URI, values);
// Toast.makeText(getApplicationContext(),uri.toString(),Toast.LENGTH_LONG).show();
System.out.println("URI :" + uri);
}
} else {
}
} else {
Toast.makeText(getApplicationContext(), "Sesioni juaj ka skaduar ju duhet te rilogoheni", Toast.LENGTH_LONG).show();
}
}
#Override
public void onFailure(Call < Quiz > call, Throwable t) {
dialog.dismiss();
}
});
}
public void loading() {
dialog = new MaterialDialog.Builder(Activity_Quiz.this)
.title("Duke hyre ne sistem!")
.content("Ju lutem prisni...")
.progress(true, 0)
.show();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
//handle the click on the back arrow click
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
int progress = (int)(millisUntilFinished / 10000);
koha.setText("" + String.format("%d : %d",
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))));
}
#Override
public void onFinish() {
//finish();
saveData.setQuizStatus("start");
Toast.makeText(getApplicationContext(), "Koha mbaroi", Toast.LENGTH_LONG).show();
}
}
}
Thank You!
Your buttons' states are only updated once since the logic is in onCreate.
Consider transferring that logic into a function and call it in the button's onClick handler after updating the rowID.
For example
private void updateButtonState() {
if (rowID > 1 && rowID < 40) {
previous_question.setEnabled(true);
next_question.setEnabled(true);
} else if (rowID == 40) {
next_question.setEnabled(false);
} else if (rowID == 1) {
previous_question.setEnabled(false);
}
}
And in your onClick
#Override
public void onClick(View v) {
rowID = rowID - 1; // + 1 if next button
updateButtonState();
...
}
I've been having this issue for about a month now and I made a different question about it here: https://stackoverflow.com/questions/38005624/activity-stops-after-certain-time?noredirect=1#comment63454873_38005624
The issue appears to be a problem with the UI thread. After a seemingly random time of running, the UI thread appears to stop doing work. Any 'Runnable' objects passed to it with '.post()' or 'runOnUIThead()' do not get run. Even a simple log message. onClickListener objects also do not fire when the issue occurs. I've had runs where it starts happening within 2 seconds of starting, I've had runs where I make it through the entire game with no issue; all on the same code.
Here is my code if you need it:
The Activity:
package edu.rit.jacob.timeturner;
import android.app.ActivityManager;
import android.app.Application;
import android.app.Dialog;
import android.content.Intent;
import android.os.Looper;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.support.annotation.StringRes;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Layout;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;
public class UniverseActivity extends AppCompatActivity {
public static final String TAG = UniverseActivity.class.getSimpleName();
private UniverseThread thread;
public UniverseThread getThread(){ return thread; }
public static int SECTORS_HEIGHT = 3;
public static int SECTORS_WIDTH = 3;
private Galaxy player;
public Galaxy getPlayer() {
return player;
}
//components:
private UniverseView surfaceView;
private ImageView playerSprite;
private ImageView otherSprite;
private TextView testText;
private SeekBar speedBar;
private ProgressBar timebar;
//Pop ups
private Dialog infoPopUp;
private Dialog startScreen;
//other Galaxies
Galaxy[] galaxies = new Galaxy[SECTORS_HEIGHT * SECTORS_WIDTH];
#Override
protected void onCreate(Bundle savedInstanceState) {
//Setup Activity
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_universe);
Runnable init = new Runnable() {
#Override
public void run() {
initInfoPopUp();
initActivityComponents();
initPlayerAndSprites();
initOtherGalaxies();
initStartScreen();
}
};
runOnUiThread(init);
thread = new UniverseThread(surfaceView.getHolder(), surfaceView);
thread.setRunning(true);
thread.start();
startScreen.setTitle("The Beginning...");
startScreen.show();
Log.d(TAG, "App launched with " + ((ActivityManager)getSystemService(ACTIVITY_SERVICE)).getLargeMemoryClass() + "MB max");
}
#Override
protected void onDestroy() {
super.onDestroy();
boolean retry = true;
while(retry){
try{
thread.join();
retry = false;
}
catch (InterruptedException e){
//try again
}
}
}
private void initStartScreen(){
startScreen = new Dialog(this);
startScreen.setContentView(R.layout.new_game_start);
((TextView)startScreen.findViewById(R.id.textView4)).setText(getString(R.string.start_game_info));
startScreen.findViewById(R.id.buttonStart).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
player.setName("" + ((EditText)startScreen.findViewById(R.id.editText)).getText());
startScreen.dismiss();
}
});
}
private void initInfoPopUp(){
infoPopUp = new Dialog(this);
infoPopUp.setContentView(R.layout.info_popup);
Button infoOption1 = (Button) infoPopUp.findViewById(R.id.option1);
Button infoOption2 = (Button) infoPopUp.findViewById(R.id.option2);
infoOption1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Option 1 clicked");
//player.incrementGas(galaxies[player.getSector() - 1].getGas());
player.merge(galaxies[player.getSector() - 1], true);
galaxies[player.getSector() - 1] = null;
infoPopUp.dismiss();
}
});
infoOption2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Option 2 clicked");
//player.incrementGas(galaxies[player.getSector() - 1].getGas() / 2);
//galaxies[player.getSector() - 1].incrementGas(-galaxies[player.getSector() - 1].getGas() / 2);
player.merge(galaxies[player.getSector() - 1], false);
infoPopUp.dismiss();
}
});
}
private void initActivityComponents(){
surfaceView = (UniverseView) findViewById(R.id.surfaceView);
testText = (TextView) findViewById(R.id.testText);
speedBar = ((SeekBar)findViewById(R.id.seekBar));
timebar = ((ProgressBar)findViewById(R.id.progressBar));
}
private void initPlayerAndSprites(){
playerSprite = (ImageView) findViewById(R.id.playerGalaxy);
player = new Galaxy("Milky Way", true, new Velocity(), playerSprite, 25.0f, 1, this);
otherSprite = (ImageView) findViewById(R.id.otherGalaxy);
//Tapping on player galaxy
playerSprite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Player sprite clicked, stopping time and bringing up window...");
speedBar.setProgress(0);
infoPopUp.setTitle(player.getName());
infoPopUp.findViewById(R.id.infoPicture).setBackgroundResource(R.drawable.random_temp_galaxy_01);
infoPopUp.findViewById(R.id.option1).setVisibility(View.INVISIBLE);
infoPopUp.findViewById(R.id.option2).setVisibility(View.INVISIBLE);
((TextView)infoPopUp.findViewById(R.id.infoText)).setText(player.toString());
infoPopUp.show();
}
});
//Tapping on other galaxy
otherSprite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(otherSprite.getVisibility() == View.VISIBLE){
Log.d(TAG, "Other sprite clicked, stopping time and bringing up window...");
speedBar.setProgress(0);
infoPopUp.setTitle(galaxies[player.getSector() - 1].getName());
infoPopUp.findViewById(R.id.infoPicture).setBackgroundResource(R.drawable.random_temp_galaxy_01);
infoPopUp.findViewById(R.id.option1).setVisibility(View.INVISIBLE);
infoPopUp.findViewById(R.id.option2).setVisibility(View.INVISIBLE);
((TextView)infoPopUp.findViewById(R.id.infoText)).setText(galaxies[player.getSector() - 1].toString());
infoPopUp.show();
}
}
});
}
private void initOtherGalaxies(){
for(Galaxy g: galaxies) g = null;
int i = 0, galaxiesNum = 0;
Log.d(TAG, "Populating the universe...");
while(i < galaxies.length){
double rand = Math.random();
if(rand <= 0.25){
galaxies[i] = new Galaxy("Random galaxy", new Velocity(0,0), otherSprite, 25.0f, i + 1, (Math.random()), this);
galaxiesNum += 1;
}
i += 1;
}
Log.d(TAG, "Universe populated with " + galaxiesNum + " galaxies.");
}
public int getSpeed(){
return speedBar.getProgress();
}
public void setTimeProgress(int progress){
try {
if (timebar.getProgress() != progress) {
switch (progress) {
case 10:
//((ProgressBar) findViewById(R.id.progressBar)).getProgress()
progress += 1;
//bring up new popup
break;
case 50:
//do stuff
break;
case 100:
//do end game stuff
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
//try again
}
}
}
timebar.setProgress(progress);
}
}
catch (NullPointerException e){
Log.d(TAG, "Failed to grab progressBar");
e.printStackTrace();
}
}
public void changeBackground(){
Runnable changeBackground = new Runnable() {
#Override
public void run() {
//Set new background
Log.d(TAG, "Changing to background " + player.getSector());
//surfaceView.setBackgroundResource(R.drawable.background01 + (player.getSector() - 1));
testText.setText("Sector: " + player.getSector());
//Check for other galaxy
if(galaxies[player.getSector() - 1] != null){
otherSprite.setVisibility(View.VISIBLE);
}
else{
otherSprite.setVisibility(View.INVISIBLE);
}
synchronized (this) {
this.notify();
}
}
};
Log.d(TAG, "Passing background runnable to the UI thread");
synchronized (changeBackground){
runOnUiThread(changeBackground);
try {
changeBackground.wait();
}
catch (InterruptedException e){
e.printStackTrace();
}
}
}
public void checkForCollision(){
if(playerSprite.getX() + (playerSprite.getWidth() / 2) >= otherSprite.getX() &&
playerSprite.getX() + (playerSprite.getWidth() / 2) <= otherSprite.getX() + otherSprite.getWidth() &&
playerSprite.getY() + (playerSprite.getHeight() / 2) >= otherSprite.getY() &&
playerSprite.getY() + (playerSprite.getHeight() / 2) <= otherSprite.getY() + otherSprite.getHeight()){
if(otherSprite.getVisibility() == View.VISIBLE){
//switch (player.)
Runnable collide = new Runnable() {
#Override
public void run() {
speedBar.setProgress(0);
otherSprite.setVisibility(View.INVISIBLE);
((TextView)infoPopUp.findViewById(R.id.infoText)).setText("");
//infoPopUp.findViewById(R.id.infoPicture).setBackgroundResource(R.drawable.hubble_merger_01);
infoPopUp.findViewById(R.id.option1).setVisibility(View.VISIBLE);
infoPopUp.findViewById(R.id.option2).setVisibility(View.VISIBLE);
infoPopUp.setTitle("Incoming!");
infoPopUp.show();
}
};
runOnUiThread(collide);
}
}
//Set gauge
Runnable setGauge = new Runnable() {
#Override
public void run() {
((GaugeView)findViewById(R.id.gaugeView)).setTargetValue(player.getGas());
}
};
runOnUiThread(setGauge);
}
}
The Thread:
package edu.rit.jacob.timeturner;
import android.content.Context;
import android.graphics.Canvas;
import android.hardware.*;
import android.hardware.SensorManager;
import android.provider.Settings;
import android.util.Log;
import android.view.SurfaceHolder;
import android.widget.ImageView;
public class UniverseThread extends Thread {
public static final String TAG = UniverseThread.class.getSimpleName();
private double time;
public double getTime(){
return time;
}
private double speed;
public double getSpeed(){
return speed;
}
private boolean running;
public void setRunning(boolean running){
this.running = running;
}
public boolean isRunning(){
return running;
}
//Reference to the UniverseActivity
private SurfaceHolder surfaceHolder;
//Reference to the UniverseView that is the background
private UniverseView universeView;
public UniverseThread(SurfaceHolder surfaceHolder, UniverseView universeView){
super();
this.surfaceHolder = surfaceHolder;
this.universeView = universeView;
running = false;
time = 0;
}
public static float x = 0, y = 0, z = 0;
#Override
public void run(){
Log.d(TAG, "Starting Game Loop");
time = 0.0;
speed = 0.0;
//SensorManager gets SENSOR_SERVICE from android
//Accesses gravity sensor
SensorManager sm = (SensorManager) this.universeView.getContext().getSystemService(Context.SENSOR_SERVICE);
sm.registerListener(new SensorEventListener() {
#Override
public void onSensorChanged(SensorEvent event) {
x = event.values[0];
y = event.values[1];
z = event.values[2];
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}, sm.getDefaultSensor(Sensor.TYPE_GRAVITY), SensorManager.SENSOR_DELAY_GAME);
//save player, velocity, and sprite
Galaxy player = ((UniverseActivity)universeView.getContext()).getPlayer();
Velocity vel = player.getVel();
ImageView sprite = player.getSprite();
boolean changeBackground;
float timesRun = 0f;
while(running){
//every 16 milliseconds (~60 Hz)
timesRun += 1;
final String testStr = "Thread has run for " + (timesRun) + " frames.";
Runnable test = new Runnable() {
#Override
public void run() {
Log.d(TAG, testStr);
}
};
if(timesRun % 60 == 0) ((UniverseActivity) universeView.getContext()).runOnUiThread(test);
//increment the time
speed = ((UniverseActivity)universeView.getContext()).getSpeed();
time += (speed / 7200.0);
((UniverseActivity)universeView.getContext()).setTimeProgress((int) time);
//update player's velocity
((UniverseActivity)universeView.getContext()).getPlayer().getVel().incrementXV(-x / 9.81f);
((UniverseActivity)universeView.getContext()).getPlayer().getVel().incrementYV(y / 9.81f);
//update player's position
//move sprite
sprite.setX((float)(sprite.getX() + (vel.getxV() * speed / 400)));
sprite.setY((float)(sprite.getY() + (vel.getyV() * speed / 400)));
changeBackground = false;
//bottom -> top
if (sprite.getY() + (sprite.getHeight() / 2) > universeView.getHeight()) {
sprite.setY(0 - (sprite.getHeight() / 2));
sprite.setX(universeView.getWidth() / 2);
player.updateSector("BOTTOM");
changeBackground = true;
}
//right -> left
if (sprite.getX() + (sprite.getWidth() / 2) > universeView.getWidth()) {
sprite.setY(universeView.getHeight() / 2);
sprite.setX(0 - (sprite.getWidth() / 2));
player.updateSector("RIGHT");
changeBackground = true;
}
//top -> bottom
if (sprite.getY() + (sprite.getHeight() / 2) < 0) {
sprite.setY(universeView.getHeight() - (sprite.getHeight() / 2));
sprite.setX(universeView.getWidth() / 2);
player.updateSector("TOP");
changeBackground = true;
}
//left -> right
if (sprite.getX() + (sprite.getWidth() / 2) < 0) {
sprite.setY(universeView.getHeight() / 2);
sprite.setX(universeView.getWidth() - (sprite.getWidth() / 2));
player.updateSector("LEFT");
changeBackground = true;
}
if(changeBackground)
{((UniverseActivity)universeView.getContext()).changeBackground();}
((UniverseActivity)universeView.getContext()).checkForCollision();
try{
this.sleep(16L);
}
catch (InterruptedException e){
e.printStackTrace();
}
}
Log.d(TAG, "Game Loop terminated");
}
}
To be clear, no exceptions or errors are being thrown during runtime. The only messages in logcat are my own and the system messages for registering a click, for example. The application does not crash and the sprite is still perfectly controllable. The main things that do not work is the changing of backgrounds, checking for a collision, and the onClickListeners.
Has anyone run into something like this before? Any help would be appreciated.
So after having narrowed the problem down to the Runnable objects I was passing to the UI thread, I took steps to minimize the amount of time I called runOnUIThread() at first it didn't seem to have any effect but eventually I stopped having this problem and that's the only thing I can contribute it to. I might eventually do some more testing to be more concrete that that was the problem and respective solution.
I need to make the android guessing game I have so far to have a limit of 3 attempts after which the message like game over will be displayed, however I have no idea how to do it as I'm still new to programming so I would appreciate your help
Android Code I have so far:
import java.util.Random;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Task1Activity extends Activity {
private TextView tvPlayer;
private EditText eName;
private Button butSubmit;
private TextView nameOutput;
private TextView tvNumber;
private EditText eNumber;
private TextView numOutput;
private Button butGuess;
private Button butStart;
private String name_output;
private String number_output;
private TextView tvTries;
private TextView tvTries2;
public static int N;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.task1_layout);
//Reference the input and output views on the interface
tvPlayer = (TextView) findViewById(R.id.tvPlayer);
eName = (EditText) findViewById(R.id.eName);
butSubmit = (Button) findViewById(R.id.butSubmit);
tvNumber = (TextView) findViewById(R.id.tvNumber);
eNumber = (EditText) findViewById(R.id.eNumber);
butGuess = (Button) findViewById(R.id.butGuess);
butStart = (Button) findViewById(R.id.butStart);
nameOutput = (TextView) findViewById(R.id.nameOutput);
numOutput = (TextView) findViewById(R.id.numOutput);
tvTries = (TextView) findViewById(R.id.tvTries);
tvTries2 = (TextView) findViewById(R.id.tvTries2);
}
public void addClick1(View Button){
name_output = eName.getText().toString(); //get the existing comments
nameOutput.setText(name_output);//Display the new comments
} public void addClick2(View Button){
Random r = new Random();
int Low = 0;
int High = 20;
N = r.nextInt(High-Low) + Low;
}
public void addClick3(View Button){
number_output = eNumber.getText().toString(); //get the existing comments
try {
int compareNum = Integer.parseInt(number_output);
if(compareNum == N){
numOutput.setText(number_output + " Good Guess!");//Display the new comments
numOutput.setBackgroundColor(Color.GREEN);
}else if(compareNum > N){
numOutput.setText(number_output + " is too HIGH!");//Display the new comments
numOutput.setBackgroundColor(Color.RED);
}else if(compareNum < N){
numOutput.setText(number_output + " is too LOW!");//Display the new comments
numOutput.setBackgroundColor(Color.RED);
}
}
catch (NumberFormatException e) {
}
}
}
You have to get a count on the clicks something like:
public void addClick2(View Button){
Random r = new Random();
int Low = 0;
int High = 20;
int count = 0;
N = r.nextInt(High-Low) + Low;
}
public void addClick3(View Button){
count++;
number_output = eNumber.getText().toString(); //get the existing comments
try {
int compareNum = Integer.parseInt(number_output);
if(compareNum == N){
numOutput.setText(number_output + " Good Guess!");//Display the new comments
numOutput.setBackgroundColor(Color.GREEN);
}else if(compareNum > N){
numOutput.setText(number_output + " is too HIGH!");//Display the new comments
numOutput.setBackgroundColor(Color.RED);
}else if(compareNum < N){
numOutput.setText(number_output + " is too LOW!");//Display the new comments
numOutput.setBackgroundColor(Color.RED);
}
}
catch (NumberFormatException e) {
}
if(count == 3){
//set your game over message
}
}
}
So I have a class that is supposed to take in a number and get the Prime factors. Those factors are then stored in an ArrayList, Factors, and printed out at the end. Problem is it only works for 4 and when I do 16 it freezes. Any help would be great!
My java class:
package com.frostbytedev.addsub;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Created by Steven on 7/4/13.
*/
public class Factor extends Activity implements View.OnClickListener{
ArrayList<Integer> Factors = new ArrayList<Integer>();
ArrayList<Integer> toAdd = new ArrayList<Integer>();
ArrayList<Integer> toRemove = new ArrayList<Integer>();
int numToFactor;
TextView FactorResults;
EditText NumberInput;
Button bFactor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.factor);
initialize();
}
private void initialize() {
FactorResults = (TextView)findViewById(R.id.tvFactors);
NumberInput = (EditText)findViewById(R.id.etNumber);
bFactor = (Button)findViewById(R.id.bFactor);
bFactor.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch(view.getId()){
case R.id.bFactor:
numToFactor = Integer.parseInt(NumberInput.getText().toString());
FactorNumber(numToFactor);
FindFactors(Factors);
PrintFactors(Factors);
}
}
private void PrintFactors(ArrayList<Integer> factors) {
//String joined = Factors.get(0)+", "+Factors.get(1);
String joined = TextUtils.join(", ", Factors);
FactorResults.setText(joined);
}
private void FactorNumber(int number) {
int multipliedFactors=1;
int i;
double middle = Math.ceil(number/2);
FactorResults.setText(String.valueOf(middle));
for(i=(int)middle;i>1;i--){
if(number%i==0){
Factors.add(i);
}
else
return;
}
for(i=0;i<Factors.size();i++){
multipliedFactors*=Factors.get(i);
}
if(multipliedFactors<number){
FactorNumber(number);
}
if(Factors.size()==0){
FactorResults.setText(number+" has no factors!");
}
}
public void FindFactors(ArrayList<Integer> factors){
int i;
for(i=0;i<factors.size();i++){
int y;
double middle;
middle = Math.ceil(factors.get(i)/2);
for(y=(int)middle;y>1;y--){
if(i%y==0){
toAdd.add(y);
toAdd.add(factors.get(i)/y);
toRemove.add(i);
RemoveExtras(toRemove);
AddNewFactors(toAdd);
FindFactors(Factors);
}
else
return;
}
}
}
private void AddNewFactors(ArrayList<Integer> toAdd) {
int i;
for(i=0;i<toAdd.size();i++){
Factors.add(toAdd.get(i));
}
}
private void RemoveExtras(ArrayList<Integer> toRemove) {
int i;
for(i=0;i<toRemove.size();i++){
Factors.remove(toRemove.get(i));
}
}
}
Try this algorithm
private void factorNumber(int n) {
for (int i = 2; i <= n / i; i++) {
while (n % i == 0) {
factors.add(i);
n /= i;
}
}
if (n > 1) {
factors.add(n);
}
}