I am working on a financial app and i have to use BigDecimal to calculate currency.Now I am trying to make one entrance activity which is searching in the SharedPreferences for a previous registration and if their is one it starts another activity , if not it starts the registration activity.The problem is the registration activity causes NumberFormatException Error while I am trying to construct a new object of time Profit (the Profit class contains BigDecimal field).Also I am not quite sure that I am using SharedPreferences right.I am not quite sure that my idea and my coding are fine because I am new at android development and i am stuck with this problem so I am giving you all the classes.
the Registration activity:
public class Registration extends Activity {
private static String enteredPassword;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final EditText password1 = (EditText) findViewById(R.id.password1);
final EditText password2 = (EditText) findViewById(R.id.password2);
final EditText availability = (EditText) findViewById(R.id.availability);
EditText profitEditText = (EditText) findViewById(R.id.profit);
Spinner spinner = (Spinner) findViewById(R.id.period_spinner);
Button registrationButton = (Button) findViewById(R.id.registrationButton);
DatePicker picker = (DatePicker) findViewById(R.id.thePicker);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.periods_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
final String balance = availability.getText().toString().replace(",",".");
String profitPeriod = ((Period) spinner.getSelectedItem()).name();
final Profit profit = new Profit("regular_profit", profitEditText.getText().toString(),
profitPeriod ,picker);
registrationButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (password1.getText().toString().equals(password2.getText().toString())) {
enteredPassword = password1.getText().toString();
Repository.setPassword(enteredPassword, mContext);
}
Repository.setBalance(balance, mContext);
Repository.setProfit(profit, mContext);
}
});
}
}
the profit activity
public class Profit {
private Date mProfitDate;
private Date mNextProfitDate;
private BigDecimal value;
public final static String TITLE = "title";
public final static String PERIOD = "period";
Profit(String title,String value, String period, DatePicker picker) {
this.mTitle = title;
if(value!=null){this.value = new BigDecimal(value);}else{ this.value = new BigDecimal("0.0");};
this.mPeriod = Period.class.cast(period);
this.mProfitDate = Repository.getDateFromPicker(picker);
}
public long getNextProfitDate(Date profitDate, Period period){
long unixProfitDate = profitDate.getTime() / 1000L;
long nextProfitDate=0;
switch (period){
case DAILY:
nextProfitDate = DateUtils.DAY_IN_MILLIS/1000 + unixProfitDate;
break;
case WEEKLY:
nextProfitDate = DateUtils.WEEK_IN_MILLIS/1000 + unixProfitDate;
break;
case MONTHLY:
Date dateNow = new Date();
dateNow.getTime();
nextProfitDate = Repository.monthsToSeconds(Calendar.getInstance()
.get(Calendar.MONTH)) + unixProfitDate;
break;
case YEARLY:
nextProfitDate = DateUtils.YEAR_IN_MILLIS/1000 + unixProfitDate;
break;
}
return nextProfitDate;
}
}
the entrance activity
public class EnterActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter);
CountDownTimer timer = new CountDownTimer(3000, 100) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
if(Repository.getPassword(mContext.getApplicationContext()).equals("No Value")){
Intent registrationIntent = new Intent(mContext, Registration.class);
startActivity(registrationIntent);
}
else{
Intent configurationIntent = new Intent(mContext, Configuration.class);
startActivity(configurationIntent);
}
}
}.start();
}
}
the Repository
public class Repository {
public static SharedPreferences sharedPreferences;
private static SharedPreferences getPrefs(Context context) {
return context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
}
public static String getPassword(Context context){
return getPrefs(context).getString(PASSWORD,"No Value");
}
public Repository() {
}
public static void setPassword(String password, Context context){
SharedPreferences.Editor editor = getPrefs(context).edit();
editor.putString(PASSWORD, password);
editor.commit();
}
public static void setBalance(String balance, Context context){
SharedPreferences.Editor editor = getPrefs(context).edit();
editor.putString(BALANCE, balance);
editor.commit();
}
public static void setProfit(Profit profit, Context context){
SharedPreferences.Editor editor = getPrefs(context).edit();
editor.putString(BALANCE, profit.getValue().toString());
editor.commit();
}
}
the output
E/AndroidRuntime: FATAL EXCEPTION: main
E/AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{/.Registration}: java.lang.NumberFormatException: Bad offset/length: offset=0 len=0 in.length=0
E/AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
E/AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
E/AndroidRuntime: at android.app.ActivityThread.access$600(ActivityThread.java:123)
E/AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime: at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:4424)
E/AndroidRuntime: at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
E/AndroidRuntime: at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime: Caused by: java.lang.NumberFormatException: Bad offset/length: offset=0 len=0 in.length=0
E/AndroidRuntime: at java.math.BigDecimal.<init>(BigDecimal.java:282)
E/AndroidRuntime: at java.math.BigDecimal.<init>(BigDecimal.java:438)
E/AndroidRuntime: at .Profit.<init>(Profit.java:41)
E/AndroidRuntime: at .Registration.onCreate(Registration.java:57)
E/AndroidRuntime: at android.app.Activity.performCreate(Activity.java:4466)
E/AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
E/AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
E/AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
E/AndroidRuntime: at android.app.ActivityThread.access$600(ActivityThread.java:123)
E/AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime: at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:4424)
E/AndroidRuntime: at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
E/AndroidRuntime: at dalvik.system.NativeStart.main(Native Method)
You instantiate a Profit in only one place in the code you presented:
Profit profit = new Profit("regular_profit", profitEditText.getText().toString(),
profitPeriod, picker);
If that causes a NumberFormatException then it must come from this code in the Profit constructor:
if(value!=null){this.value = new BigDecimal(value);}else{ this.value = new BigDecimal("0.0");};
Since the value String will have come from invoking toString() on an object, you can rely on it to not be null (and anyway, if it were null then you would end up at new BigDecimal("0.0"), and you can verify for yourself that that works fine). That leaves us with new BigDecimal(value) as the culprit. The docs for this constructor provide details of the expected format of the argument string. If the argument does not comply with that format then a NumberFormatException will be thrown.
Among the more likely malformed strings that one might imagine in a scenario such as you describe is an empty string, which is not the same as null in Java. Given that the text is coming from a UI field, you also have to watch out for fun and difficult-to-spot malformations such as leading and trailing whitespace.
Perhaps it would be better to write the affected part of the constructior like so:
if (value != null) {
value = value.trim();
this.value = value.length() == 0 ? BigDecimal.ZERO : new BigDecimal(value);
} else {
this.value = BigDecimal.ZERO;
}
Do note that even with that change, this constructor will still throw NumberFormatException in the event of other kinds of malformation. Wherever you are uncertain about the validity of the data, you should be prepared to handle such an exception.
You aren't parsing your string to a Big Decimal correctly.
The following in your Profit contructor:
if(value!=null)
{
this.value = new BigDecimal(value);
}
else
{
this.value = new BigDecimal("0.0");
}
Needs to parse the string to a BigDecimal. Like the following where this.value is of type BigDecimal:
this.value = (BigDecimal) decimalFormat.parse(value);
Also keep in mind that decimalFormat.parse can throw a ParseException. You will need to handle it with try/catch or throw it.
Related
I was using an integer for the money factor in this little test app but I realized that long was more appropriate and I changed the code so that money is a long instead of an int and I changed SharedPreferences appropriately as well, however it does not work wheras it did when I used int. Thank you for the help!
public class Home extends AppCompatActivity {
SharedPreferences pref;
SharedPreferences.Editor editor;
Intent intent;
TextView home_money_view;
long money; // this is the variable that is causing problems
int initial;
final long TEST = (long)-1;
int gold_pieces;
int gold_price = 50;
TimerTask timerTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
home_money_view = (TextView) findViewById(R.id.home_money_view)
pref = getApplicationContext().getSharedPreferences("MY_PREFS", MODE_PRIVATE);
editor = pref.edit();
money = pref.getLong("temp_money",Long.MIN_VALUE); // get value
if (money==Long.MIN_VALUE){
money=0;
}
gold_pieces = pref.getInt("temp_gold",-1);
if (gold_pieces==-1){
gold_pieces=0;
}
initial = pref.getInt("initial",0);
money+=initial;
editor.putInt("initial",0);
editor.commit();
home_money_view = (TextView) findViewById(R.id.home_money_view);
home_money_view.setText(money+"");
editor.commit();
}
public void backToSplash(View view){
intent = new Intent(Home.this,BusinessSelector.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
public void goToSecondView(View view){
long temp_money = money;
editor.putLong("temp_money",temp_money); // set value
int temp_gold = gold_pieces;
editor.putInt("temp_gold",temp_gold);
editor.commit();
intent = new Intent(Home.this,SecondView.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
public void goToOtherView(View view) {
long temp_money = money;
editor.putLong("temp_money",temp_money); // set value
int temp_gold = gold_pieces;
editor.putInt("temp_gold", temp_gold);
editor.commit();
intent = new Intent(Home.this, Next.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
Logcat:
04-13 19:01:03.675 12896-12896/com.exampleryancocuzzo.ryan.markettycoon E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.exampleryancocuzzo.ryan.markettycoon/com.exampleryancocuzzo.ryan.markettycoon.Home}: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
at android.app.SharedPreferencesImpl.getLong(SharedPreferencesImpl.java:228)
at com.exampleryancocuzzo.ryan.markettycoon.Home.onCreate(Home.java:56)
at android.app.Activity.performCreate(Activity.java:4466)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
I need to set Listener for Activity Class from BroadcastReceiver Class But here in my below code I am getting null pointer exception in BroadcastReceiver class..
Here is my code
Activity Class
public class MainActivity extends ActionBarActivity implements TheListener
{
Message_Incomingsms jv_class_Message_Incomingsms;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
jv_class_Message_Incomingsms = new Message_Incomingsms();
jv_class_Message_Incomingsms.setSmsReceivedistener(this);
}
#Override
public void onSmsReceived(String jv_string_address, String jv_string_MessageText)
{
Toast.makeText(getApplicationContext(),"This Message is from Lister number is "+jv_string_address +" Message is "+jv_string_MessageText,Toast.LENGTH_LONG).show();
//Doing some Activity.....
}
}
Interface
public void setSmsReceivedistener(Context context)
{
this.jv_TheListener = (TheListener)context;
}
BroadCastReceiver Class
public class Message_Incomingsms extends BroadcastReceiver
{
String jv_string_phone_received_Number;
String jv_string_phone_received_messageText;
public TheListener jv_TheListener;
#Override
public void onReceive(Context context, Intent intent)
{
Log.d("Received","OnReceive method is called");
jv_smsmanager_incoming_sms = SmsManager.getDefault();
jv_bundle_incoming_sms = intent.getExtras();
if(jv_bundle_incoming_sms!=null)
{
Object[] jv_pdusObj_incoming_sms = (Object[]) jv_bundle_incoming_sms.get("pdus");
for(int jv_i = 0; jv_i < jv_pdusObj_incoming_sms.length ;jv_i++)
{
SmsMessage jv_current_message = SmsMessage.createFromPdu((byte[]) jv_pdusObj_incoming_sms[jv_i]);
jv_string_phone_received_Number =jv_current_message.getDisplayOriginatingAddress();
jv_string_phone_received_messageText = jv_current_message.getDisplayMessageBody();
}
//Here Below line is problem for me Always am getting null value for (jv_TheListener)
//Why value is not getting assigned for this (jv_TheListener) always
jv_TheListener.onSmsReceived(jv_string_phone_received_Number,jv_string_phone_received_messageText);
}
}
public void setSmsReceivedistener(Context context)
{
this.jv_TheListener = (TheListener)context;
}
}
Please provide me solution for above BroadCastClass code where am always getting null exception for (jv_TheListener)
log Cat ( I removed some lines for in code for not to confuse.. so dont refer linenumber based on below error)
04-18 23:45:12.268 4064-4064/com.talkeasy.elavarasans.creativeactionbar E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start receiver com.talkeasy.elavarasans.creativeactionbar.Message_Incomingsms: java.lang.NullPointerException
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2153)
at android.app.ActivityThread.access$1500(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1208)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4448)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.talkeasy.elavarasans.creativeactionbar.Message_Incomingsms.onReceive(Message_Incomingsms.java:53)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2146)
at android.app.ActivityThread.access$1500(ActivityThread.java:127)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1208)
Thanks in Advance...
Building on a theme from yesterday...I'm getting an NPE accessing a method in a singleton Application class from within an AlertDialog.
Activity SavedMealsActivity sets OnLongClickListenerSavedMeals as the listener for a series of TextViews in a ScrollView. OnLongClickListenerSavedMeals is defined as a separate class.
OnLongClickListenerSavedMeals displays an AlertDialog which gives the option of going to a different Activity, but it first needs to fire the methods of an Application class which is defined as a singleton (MealTimerApplication). This is the first line of the onClick method (line 25 in the first code sample below), and it throws the NPE because the activity is null at the time.
I've tried passing in the activity from the calling Activity (SavedMealsActivity) but for some reason it's not working as I'd hoped. Any ideas?
OnLongClick listener class - OnLongClickListenerSavedMeals:
public class OnLongClickListenerSavedMeals implements OnLongClickListener {
Context context;
String id;
private Activity activity;
public OnLongClickListenerSavedMeals(Activity activity) {
this.activity = activity;
this.context = activity;
}
#Override
public boolean onLongClick(View view){
// TODO Auto-generated method stub
this.context = context;
id = view.getTag().toString();
final CharSequence[] items = { "Edit", "Delete" };
//Set activity to allow context to be used in the OnClickListener/onClick method below
this.activity = activity;
new AlertDialog.Builder(context).setTitle("Meal Item")
.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (item == 0) {
//Set the global meal_id variable and invoke the MealActivity
((MealTimerApplication) activity.getApplication()).setMealId(Long.getLong(id));
Intent myIntent = new Intent(activity.getBaseContext(),MealActivity.class);
activity.startActivityForResult(myIntent, 0);
}
else if (item == 1) {
boolean deleteSuccessful = new TableControllerMeal(context).delete(id);
if (deleteSuccessful){
Toast.makeText(context, "Record was deleted.", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context, "Unable to delete record.", Toast.LENGTH_SHORT).show();
}
((SavedMealsActivity) context).readRecords();
}
dialog.dismiss();
}
}).show();
return false;
}
Calling Activity - SavedMealsActivity:
public class SavedMealsActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_saved_meals);
//Read saved meal records from the database and display them
readRecords();
}
public void readRecords() {
LinearLayout linearLayoutRecords = (LinearLayout) findViewById(R.id.linearLayoutRecords);
linearLayoutRecords.removeAllViews();
List<meal> meal = new TableControllerMeal(this).read();
if (meal.size() > 0) {
for (meal obj : meal) {
long id = obj.id;
String MealDesc = obj.meal_desc;
int MealMinutes = obj.meal_ready_time;
String textViewContents = MealDesc + " - ready at "
+ Utilities.formatTime(MealMinutes);
TextView textViewItem = new TextView(this);
textViewItem.setPadding(0, 10, 0, 10);
textViewItem.setText(textViewContents);
textViewItem.setTag(Long.toString(id));
textViewItem.setOnLongClickListener(new OnLongClickListenerSavedMeals(this));
linearLayoutRecords.addView(textViewItem);
}
}
else {
TextView Item = new TextView(this);
Item.setPadding(8, 8, 8, 8);
Item.setText("No records yet.");
linearLayoutRecords.addView(Item);
}
}
Application class:
public class MealTimerApplication extends Application {
private static MealTimerApplication singleton;
private long mealId = 0;
// Returns the application instance
public static MealTimerApplication getInstance() {
return singleton;
}
public final void onCreate() {
super.onCreate();
singleton = this;
}
public void setMealId(long mealId) {
this.mealId = mealId;
}
public long getMealId() {
return this.mealId;
}
}
Logcat:
05-28 16:48:03.637: E/AndroidRuntime(4241): java.lang.NullPointerException
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.ian.mealtimer.OnLongClickListenerSavedMeals$1.onClick(OnLongClickListenerSavedMeals.java:39)
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:941)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AdapterView.performItemClick(AdapterView.java:299)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AbsListView.performItemClick(AbsListView.java:1113)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2904)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.widget.AbsListView$3.run(AbsListView.java:3638)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.os.Handler.handleCallback(Handler.java:733)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.os.Handler.dispatchMessage(Handler.java:95)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.os.Looper.loop(Looper.java:136)
05-28 16:48:03.637: E/AndroidRuntime(4241): at android.app.ActivityThread.main(ActivityThread.java:5017)
05-28 16:48:03.637: E/AndroidRuntime(4241): at java.lang.reflect.Method.invokeNative(Native Method)
05-28 16:48:03.637: E/AndroidRuntime(4241): at java.lang.reflect.Method.invoke(Method.java:515)
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
05-28 16:48:03.637: E/AndroidRuntime(4241): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
05-28 16:48:03.637: E/AndroidRuntime(4241): at dalvik.system.NativeStart.main(Native Method)
You get NPE because of autoboxing. Long.getLong(String) is not what you actually you need, check its description:
Returns the Long value of the system property identified by string.
It definitely returns null in your case. Moreover it returns null reference to Long object, but your MealTimerApplication.setMealId expects argument with primitive type long. Here is the point where auto-boxing implicitly trying to cast your Long object returned by getLong method to the long primitive. But as value was null auto-boxing fails and you get NPE.
You should just use Long.valueOf(String) instead of Long.getLong(String).
I am very new to android. I have a counter on some SomeActivity, but when I get to the page corresponding to SomeActivity, my app crashes :
final TextView counter = (TextView) findViewById(R.id.laws_counter);
ImageView handDown = (ImageView) findViewById(R.id.handViewDown);
counter.setText("" + 0);
I want that on click of the handown, the counter is idented by -1. Here's
handDown.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(NewsActivity.this,
"The favorite list would appear on clicking this icon",
Toast.LENGTH_LONG).show();
setDown();
}
private void setDown() {
String count = counter.getText().toString();
int now_count = Integer.parseInt(count) +1;
counter.setText(String.valueOf(now_count));
}
});
Is this code correct ?
Update : here's the logcat
10-22 00:18:05.579: ERROR/AndroidRuntime(378): FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.donnfelker.android.bootstrap/com.donnfelker.android.bootstrap.ui.NewsActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.donnfelker.android.bootstrap.ui.NewsActivity.onCreate(NewsActivity.java:41)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
... 11 more
There are many ways that you can implement that functionality but think this would be an easy solution.
Make a helper method:
public class PreferencesData {
public static void saveInt(Context context, String key, int value) {
SharedPreferences sharedPrefs = PreferenceManager
.getDefaultSharedPreferences(context);
sharedPrefs.edit().putInt(key, value).commit();
}
public static int getInt(Context context, String key, int defaultValue) {
SharedPreferences sharedPrefs = PreferenceManager
.getDefaultSharedPreferences(context);
return sharedPrefs.getInt(key, defaultValue);
}
}
Then simply call the putInt method to save the counter in any Activity and getInt to get it again in any other Activity. As long as you use the same key both places.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
In my app, the user has 3 different types of quizzes they can choose. When they choose one of quiz types called "levels", I get a NullPointerException. The order of the algorithm for "levels" is the same as when the game type is "original". You can see this in the code below. It is hard to explain why the algorithms are the same so I will spare you those details but just accept the algorithms are the same for now. :)
Why am I getting this NPE exception with the quiz/game type is "levels" but not when the quiz/game type is "original" even though the code/algorithm for them are the same?
public class QuestionView extends Activity {
int correctAnswers = 0;
int wrongAnswers = 0;
int answer = 0;
int i = 0;
long score = 0;
long startTime = 20000;
long interval = 1000;
long points;
boolean timerHasStarted = false;
String category;
Button answer1, answer2, answer3, answer4;
TextView question, pointCounter, questionNumber, timeCounter, timeremaining;
ArrayList<Question> queries;
public static ArrayList<Long> pointsPerQuestion = new ArrayList<Long>(10);
Timer cdTimer;
ProgressBar bar;
Context c;
Singleton singleton = Singleton.getInstance();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.questionview);
c = this;
answer1 = (Button)findViewById(R.id.answer1);
answer2 = (Button)findViewById(R.id.answer2);
answer3 = (Button)findViewById(R.id.answer3);
answer4 = (Button)findViewById(R.id.answer4);
question = (TextView)findViewById(R.id.question);
questionNumber = (TextView)findViewById(R.id.questionnumber);
timeremaining = (TextView)findViewById(R.id.timeremaining);
category = getIntent().getStringExtra("category");
queries = getIntent().getParcelableArrayListExtra("queries");
pointsPerQuestion.clear();
if(singleton.getGameType() == "levels") {
if(singleton.getLevel() <= 10) {
cdTimer = new Timer(startTime, interval);
bar = (ProgressBar)findViewById(R.id.progressbar);
bar.setIndeterminate(false);
bar.setMax(20000);
loadLevelsQuizTen();
}
//...
} else if (singleton.getGameType() == "original") {
cdTimer = new Timer(startTime, interval);
bar = (ProgressBar)findViewById(R.id.progressbar);
bar.setIndeterminate(false);
bar.setMax(20000);
loadOriginalQuiz();
} else if (singleton.getGameType() == "freeplay") {
loadFreeplayQuiz();
}
}
public void loadFreeplayQuiz() {
//...
}
public void loadLevelsQuizTen() {
if(i == 10) {
cdTimer.cancel();
endQuiz();
} else {
if(!timerHasStarted) {
cdTimer.start();
timerHasStarted = true;
} else {
cdTimer.start();
timerHasStarted = false;
}
//answer = queries.get(i).getCorrectAnswer(); //NULLPOINTEREXCEPTION HERE
answer = 2;
question.setText(queries.get(i).getQuery()); // I COMMENTED OUT ABOVE LINE OF CODE AND NOW NPE IS NOW HERE
answer1.setText(queries.get(i).getA1());
answer2.setText(queries.get(i).getA2());
answer3.setText(queries.get(i).getA3());
answer4.setText(queries.get(i).getA4());
answer1.setOnClickListener(new OnClickListener() {
//...
}
});
answer2.setOnClickListener(new OnClickListener() {
//...
});
answer3.setOnClickListener(new OnClickListener() {
//...
});
answer4.setOnClickListener(new OnClickListener() {
//...
});
}
}
public void loadOriginalQuiz() {
if(i == 10) {
cdTimer.cancel();
endQuiz();
} else {
if(!timerHasStarted) {
cdTimer.start();
timerHasStarted = true;
} else {
cdTimer.start();
timerHasStarted = false;
}
answer = queries.get(i).getCorrectAnswer();
question.setText(queries.get(i).getQuery());
answer1.setText(queries.get(i).getA1());
answer2.setText(queries.get(i).getA2());
answer3.setText(queries.get(i).getA3());
answer4.setText(queries.get(i).getA4());
answer1.setOnClickListener(new OnClickListener() {
//...
});
answer2.setOnClickListener(new OnClickListener() {
//...
});
answer3.setOnClickListener(new OnClickListener() {
//...
});
answer4.setOnClickListener(new OnClickListener() {
//...
});
}
}
public ArrayList<Question> getQueries() {
return queries;
}
public static ArrayList<Long> getPointsPerQuestion() {
//...
}
public void correct() {
pointsPerQuestion.add(points);
score = score + points;
i++;
if(singleton.getGameType() == "original") {
loadOriginalQuiz();
} else if(singleton.getGameType() == "levels") {
loadLevelsQuizTen();
}
}
public void incorrect() {
long zero = 0;
pointsPerQuestion.add(zero);
i++;
loadOriginalQuiz();
}
public class Timer extends CountDownTimer {
public Timer(long startTime, long interval) {
super(startTime, interval);
}
#Override
public void onFinish() {
points = 0;
if(i >= 9) {
cdTimer.cancel();
pointsPerQuestion.add(points);
endQuiz();
} else {
wrongAnswers++;
incorrect();
}
}
#Override
public void onTick(long millisUntilFinished) {
bar.setProgress((int) millisUntilFinished);
points = (millisUntilFinished / 200) + 1;
timeremaining.setText("Score remaining: " + points);
if(i < 10) {
questionNumber.setText(c.getResources().getString(R.string.question) + " " + (i + 1) + " " + c.getResources().getString(R.string.of10));
}
}
}
public void endQuiz() {
Intent intent = new Intent(QuestionView.this, Results.class);
intent.putExtra("correctAnswers", correctAnswers);
intent.putExtra("wrongAnswers", wrongAnswers);
intent.putExtra("score", score);
intent.putExtra("pointsPerQuestion", pointsPerQuestion);
intent.putParcelableArrayListExtra("queries", queries);
intent.putExtra("category", category);
startActivity(intent);
}
public void onStop() {
super.onStop();
}
public void onResume() {
super.onResume();
}
}
LogCat
06-14 20:44:45.413: E/AndroidRuntime(1335): java.lang.RuntimeException: Unable to start activity ComponentInfo{matt.lyons.bibletrivia.lite/matt.lyons.bibletrivia.lite.QuestionView}: java.lang.NullPointerException
06-14 20:44:45.413: E/AndroidRuntime(1335): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
06-14 20:44:45.413: E/AndroidRuntime(1335): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
06-14 20:44:45.413: E/AndroidRuntime(1335): at android.app.ActivityThread.access$600(ActivityThread.java:141)
06-14 20:44:45.413: E/AndroidRuntime(1335): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
06-14 20:44:45.413: E/AndroidRuntime(1335): at android.os.Handler.dispatchMessage(Handler.java:99)
06-14 20:44:45.413: E/AndroidRuntime(1335): at android.os.Looper.loop(Looper.java:137)
06-14 20:44:45.413: E/AndroidRuntime(1335): at android.app.ActivityThread.main(ActivityThread.java:5041)
06-14 20:44:45.413: E/AndroidRuntime(1335): at java.lang.reflect.Method.invokeNative(Native Method)
06-14 20:44:45.413: E/AndroidRuntime(1335): at java.lang.reflect.Method.invoke(Method.java:511)
06-14 20:44:45.413: E/AndroidRuntime(1335): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
06-14 20:44:45.413: E/AndroidRuntime(1335): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
06-14 20:44:45.413: E/AndroidRuntime(1335): at dalvik.system.NativeStart.main(Native Method)
06-14 20:44:45.413: E/AndroidRuntime(1335): Caused by: java.lang.NullPointerException
06-14 20:44:45.413: E/AndroidRuntime(1335): at matt.lyons.bibletrivia.lite.QuestionView.loadLevelsQuizTen(QuestionView.java:195)
06-14 20:44:45.413: E/AndroidRuntime(1335): at matt.lyons.bibletrivia.lite.QuestionView.onCreate(QuestionView.java:80)
06-14 20:44:45.413: E/AndroidRuntime(1335): at android.app.Activity.performCreate(Activity.java:5104)
06-14 20:44:45.413: E/AndroidRuntime(1335): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
06-14 20:44:45.413: E/AndroidRuntime(1335): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
Why "accept"? That might be the fatal flaw in your argument.
Here's the problem:
Caused by: java.lang.NullPointerException
06-14 20:44:45.413: E/AndroidRuntime(1335): at matt.lyons.bibletrivia.lite.QuestionView.loadLevelsQuizTen(QuestionView.java:195)
Go to line 195 in the QuestionView.java file, look at the object references on that line, and see which one you failed to initialize.
The sooner you stop telling yourself that everything is fine and start looking at what's really happening, the sooner you'll fix the problem and move on.
You should not be duplicating any code. You should encapsulate it in a single method call and calling it in both places. This is a recipe for error.
You have lots of other issues. You use a private data member i to do different things in different methods. It's not synchronized in any way that I can see. I see no reason why that value couldn't be a method parameter and passed in. That would be more more thread safe.
When you're doing things like that, comparing Strings with ==, and duplicating code it puts everything you've done in doubt for me. No wonder you're having trouble. Voting to close.
Set a breakpoint where you are getting the NPE and check the values of your variables. I would guess either queries is null (not setting or getting from intent bundle correctly), or queries.get(i) is null.
you get the error because you are calling 2 different methods. In levels you call loadLevelsQuizTen();, in original you call loadOriginalQuiz();
Despite the fact you say they are the same, they aren't. I'd use a debugger to step through the method and figure out what is null and why.