How can I fix this android code bug that's hidden?
Am learning android and have followed a tutorial to develop a tip calculator, it's been a really good tutorial, however have completed it and nothing's happening when I run it in the emulator suddenly, just get either a force close or a blank screen (it's fairly unpredictable).
The only clue I can get when I debug is the following message: [2010-12-05 22:02:01 - Tip Calculator] ActivityManager: Warning: Activity not started, its current task has been brought to the front
My code's below, any helpers or pointers on how I can start debugging/fixing this would be most appreciated!
package com.tipcalc;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.RadioGroup.OnCheckedChangeListener;
public class tipCalc extends Activity {
// Widgets in the Application
private EditText txtAmount;
private EditText txtPeople;
private EditText txtTipOther;
private RadioGroup rdoGroupTips;
private Button btnCalculate;
private Button btnReset;
private TextView txtTipAmount;
private TextView txtTotalToPay;
private TextView txtTipPerPerson;
// For the id of radio button selected
private int radioCheckedId = -1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Access the various widgets by their id in R.java
txtAmount = (EditText) findViewById(R.id.txtAmount);
// On app load, the cursor should be in the amount field
txtAmount.requestFocus();
txtPeople = (EditText) findViewById(R.id.txtPeople);
txtTipOther = (EditText) findViewById(R.id.txtTipOther);
rdoGroupTips = (RadioGroup) findViewById(R.id.rdoGroupTips);
btnCalculate = (Button) findViewById(R.id.btnCalculate);
// On app load the calculate button is disabled
btnCalculate.setEnabled(false);
/*
* Attach an OnCheckedChangeListener to the radio
* Group to monitor the radio buttons selected by user
*
*/
rdoGroupTips.setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
public void onCheckedChanged(RadioGroup group, int checkedId){
// Enable/Disable Other Percentage tip field
if (checkedId == R.id.Radio15 || checkedId == R.id.Radio20){
txtTipOther.setEnabled(false);
// Also enable the calculate button if Total Amount and no of people fields
// have valid values.
btnCalculate.setEnabled(txtAmount.getText().length() > 0
&& txtPeople.getText().length() > 0
);
}
if (checkedId == R.id.RadioOther){
// enable the other % tip field
txtTipOther.setEnabled(true);
// set the focus to this field
txtTipOther.requestFocus();
/*
* Enable the calc button if total amount and no of people
* fields have valid values. Also ensure that the user has
* entered an Other Tip % Value before enabling the calc button
*/
btnCalculate.setEnabled(
txtAmount.getText().length() > 0
&& txtPeople.getText().length() > 0
&& txtTipOther.getText().length() > 0
);
// work out the % rate chosen by the user
radioCheckedId = checkedId;
}
}});
/*
* Create a KeyListener to the tip amount, no of people and other tip % fields
*
*/
txtAmount.setOnKeyListener(mKeyListener);
txtPeople.setOnKeyListener(mKeyListener);
txtTipOther.setOnKeyListener(mKeyListener);
// Attach listener to the Calc and Reset Buttons
btnCalculate.setOnClickListener(mClickListener);
btnReset.setOnClickListener(mClickListener);
}
/*
* OnKeyListener Special Routine
*/
private OnKeyListener mKeyListener = new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch (v.getId()) {
case R.id.txtAmount:
case R.id.txtPeople:
btnCalculate.setEnabled(txtAmount.getText().length() > 0
&& txtPeople.getText().length() > 0);
break;
case R.id.txtTipOther:
btnCalculate.setEnabled(txtAmount.getText().length() > 0
&& txtPeople.getText().length() > 0
&& txtTipOther.getText().length() > 0);
break;
}
return false;
}
};
// ClickListener for the calc and reset buttons
private OnClickListener mClickListener = new OnClickListener(){
@Override
public void onClick(View v){
if(v.getId() == R.id.btnCalculate){
calculate();
} else {
reset();
}
}
};
// Resets the results text views at the bottom of the screen as well as resets the text fields and radio buttons
private void reset() {
txtTipAmount.setText("");
txtTotalToPay.setText("");
txtTipPerPerson.setText("");
txtAmount.setText("");
txtPeople.setText("");
txtTipOther.setText("");
rdoGroupTips.clearCheck();
rdoGroupTips.check(R.id.Radio15);
// set focus on the first field
txtAmount.requestFocus();
}
// Calculate the tip as per data entered by the user
private void calculate() {
Double billAmount = Double.parseDouble(
txtA开发者_开发问答mount.getText().toString());
Double totalPeople = Double.parseDouble(
txtPeople.getText().toString());
Double percentage = null;
boolean isError = false;
if (billAmount < 1.0) {
showErrorAlert("Enter a vlaid Total Amount.",
txtAmount.getId());
isError = true;
}
if (totalPeople < 1.0) {
showErrorAlert("Enter a valid value for No. of people.",
txtPeople.getId());
isError = true;
}
// If user never changes radio, then verify 15% is correct
if (radioCheckedId == -1) {
radioCheckedId = rdoGroupTips.getCheckedRadioButtonId();
}
if (radioCheckedId == R.id.Radio15) {
percentage = 15.00;
} else if (radioCheckedId == R.id.Radio20) {
percentage = 20.00;
} else if (radioCheckedId == R.id.RadioOther) {
percentage = Double.parseDouble(
txtTipOther.getText().toString());
if (percentage < 1.0) {
showErrorAlert("Enter a valid Tip percentage",
txtTipOther.getId());
isError = true;
}
}
// If all fields are valid, then calc the tips
if(!isError) {
Double tipAmount = ((billAmount * percentage) / 100);
Double totalToPay = billAmount + tipAmount;
Double perPersonPays = totalToPay / totalPeople;
txtTipAmount.setText(tipAmount.toString());
txtTotalToPay.setText(totalToPay.toString());
txtTipPerPerson.setText(perPersonPays.toString());
};}
// Show the alerts dialogs
// @param errorMessage - String the Error message to show
// @param fieldId - id of the field which caused the error
private void showErrorAlert(String errorMessage,
final int fieldId) {
new AlertDialog.Builder(this).setTitle("Error")
.setMessage(errorMessage).setNeutralButton("Close",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
findViewById(fieldId).requestFocus();
}
}).show();
};
}
That warning means that it didn't install a new version because your code didn't change from the version that's on the emulator. You can just go to the app drawer and run the application again to bring it to the front, or make a change in your code and rerun it.
Also, you posted WAY too much code for the tiny description of your problem.
If your program is not running on emulator and you get "either a force close or a blank screen", you might have not followed the tutorial correctly. You might be missing some permissions in your manifest file, or there might not be images required in drawable folder or any other mistake. You have to give the log cat output of your errors.
Secondly if you get "ActivityManager: Warning: Activity not started, its current task has been brought to the front" , and to run and install your program again . Quick hack is to add some alphabets in your code example "abbbbb" and then delete them, save your program again and then re run it .
Hope it helps :D
"Activity not started, its current task has been brought to the front" just means that the activity is not reinstalled and it is also not really restarted but was still running in the background and that's why was only brought back to front. You can force the emulator to restart the app by using Android Debug Bridge (ADB) and kill the processes there that are associated with your activity.
That's the answer for your first question. To solve the problem, it is necessary that you post your stack trace you get when the force close message appears. You can copy this stacktrace from Logcat.
精彩评论