Hello,
I write the program code for an abstract class, the essence of it is the processing of two buttons "<", ">" one increases something (a value in a field) the other decreases accordingly. The point is that with a short press there is a one-time change, with a long press of a button, a multiple change in something while the rate of change gradually begins to grow.
In particular, I have now created an application in which the calendar is displayed (using the datePicker) and two buttons "<", ">" that change the current month. I handle the buttons in a separate thread.
The problem is that randomly, both with a long and short press of the buttons "<", ">", my program crashes. Sometimes it also crashes when you press the "<", ">" buttons too quickly.
I suspect something has done with Threads. But specifically what is wrong can not yet find.
Please tell me what could be the problem?
Thank you very much in advance.
The code of the program of the abstract class for handling pressing the buttons "<", ">".
I would also like to explain how a long click works. After a long press on the "<", ">" button, onLongClickListener is triggered. Next, the iteration process begins, some action is repeated (the abstract class actInLongClickIncrement () ) as soon as the user lifts his finger from the button OnTouchListener fires and the iteration process ends.
Processing a short click occurs only one basic action is described in the abstract class actInShortClickIncrement () .
Here are the listeners:
/** * Function set listeners for increment button {@link #mButton_Increment}. * Listeners: OnLongListener, OnClickListener, OnTouchListener; */ public void setButtonIncrementListeners(){ // Listener for long pushing on increment button mButton_Increment.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { // Listener triggered so allow incrementing mAllowIncrement = true; /** Determine user actions in this listener */ onLongClickIncrementActions(); // Build new thread for handler long pushing on button increment. // Realize incrementing algorithm `mRepeatIncrementHandler.post(new RepeatIncrement());` runLongClickIncrementing(); return true; } }); // Listener for short pushing on increment button mButton_Increment.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Listener triggered so allow incrementing mAllowIncrement = true; // Build new thread for handler short pushing on button increment. // Realize incrementing algorithm runShortClickIncrementing(); } }); // Listener for touch increment button // It uses for detect moment lifting up finger of user from button. // If it occur than stop incrementing in thread. mButton_Increment.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if ((event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) && mAllowIncrement) { mAllowIncrement = false; } return false; } }); } Here is the processing of pressing. Handling a long press on the ">" button:
/** * Function handle long click on {@link #mButton_Increment} * * Called from function: * @see #setButtonIncrementListeners() */ public void runLongClickIncrementing(){ Log.d(TAG, "Method: runLongClickIncrementing()"); mRunLongIncrementingHandler = new Runnable() { /** For send message about updating mValue */ Message msgLongIncrement; @Override public void run() { /** if onLongClick {@link #setButtonIncrementListeners()} triggered than * {@link #mAllowIncrement = true} (allow incrementing) so begin increment */ if ( mAllowIncrement ){ /** Do some actions */ actInLongClickIncrement(); /** * For handle message */ msgLongIncrement = mViewObjectLongClickIncrementHandler.obtainMessage(); Bundle bundle = new Bundle(); /** Display in textView have to occur in intermediate handler object * {@link timeHandler}. */ bundle.putString(mDISP_VIEW_OBJECT_LONG_INCREMENT, "disp_object"); msgLongIncrement.setData(bundle); mViewObjectLongClickIncrementHandler.sendMessage(msgLongIncrement); /** Repeat */ mRepeatIncrementHandler.postDelayed(mRunLongIncrementingHandler, mDelayBetweenIterations); } } }; if (mAllowIncrement == false){ mLongIncrementThread.interrupt(); } /** There is run in separate thread. */ mLongIncrementThread = new Thread(mRunLongIncrementingHandler); mLongIncrementThread.start(); /** Handler for display object value */ mViewObjectLongClickIncrementHandler = new Handler() { @Override public void handleMessage(Message msg) { /** Check message */ Bundle bundle = msg.getData(); bundle.getString(mDISP_VIEW_OBJECT_LONG_INCREMENT); /** Set new mean in view object*/ updateViewObject(); } }; } Processing a short click on the ">" button:
/** * Function handle short click on {@link #mButton_Increment} * * Called from function: * @see #setButtonIncrementListeners() */ public void runShortClickIncrementing(){ Log.d(TAG, "Function: runShortClickIncrementing()"); mRunShortIncrementingHandler = new Runnable() { /** For send message about updating mValue */ Message msgShortIncrement; @Override public void run() { /** if onLongClick {@link #setButtonIncrementListeners()} triggered than * {@link #mAllowIncrement = true} (allow incrementing) so begin increment */ if ( mAllowIncrement ){ /** Do some actions */ actInShortClickIncrement(); /** * For handle message */ msgShortIncrement = mViewObjectShortClickIncrementHandler.obtainMessage(); Bundle bundle = new Bundle(); /** Display in textView have to occur in intermediate handler object * {@link timeHandler}. */ bundle.putString(mDISP_VIEW_OBJECT_SHORT_INCREMENT, "disp_object"); msgShortIncrement.setData(bundle); mViewObjectShortClickIncrementHandler.sendMessage(msgShortIncrement); } } }; if (mAllowIncrement == false){ mShortIncrementThread.interrupt(); } /** There is run in separate thread. */ mShortIncrementThread = new Thread(mRunShortIncrementingHandler); mShortIncrementThread.start(); /** Handler for display object value */ mViewObjectShortClickIncrementHandler = new Handler() { @Override public void handleMessage(Message msg) { /** Check message */ Bundle bundle = msg.getData(); bundle.getString(mDISP_VIEW_OBJECT_SHORT_INCREMENT); /** Set new mean in view object*/ updateViewObject(); } }; } Implementing actInLongClickIncrement in another class to change the calendar month ( datePicker object) with a long press on the ">" button:
@Override public void actInLongClickIncrement() { /** Forbid complete of {@link android.widget.DatePicker.OnDateChangedListener} */ isAllowReturnToSelect = false; /** Increase counter in every step */ mMonthCounter++; /** If {@link #mMonthCounter} is multiple of {@link #mMULTIPLICITY_FACTOR} * than double {@link #mMonthValue] that increase faster month */ if (mMonthCounter % mMULTIPLICITY_FACTOR == 0){ mMonthValue *= 2; } /** Get previous month */ dateOfK.add(Calendar.MONTH, mMonthValue); } Implementing actInShortClickIncrement in another class to change the calendar month ( datePicker object) with a short press on the ">" button ::
@Override public void actInShortClickIncrement() { /** Forbid complete of {@link android.widget.DatePicker.OnDateChangedListener} */ isAllowReturnToSelect = false; /** Get next month */ dateOfK.add(Calendar.MONTH, 1); } Implementing the ** updateViewObject ** method to display the calendar month change ( datePicker object):
@Override public void updateViewObject() { /** Update new date in {@link #mDatePicker_CalendarSetDate} object */ mDatePicker_CalendarSetDate.updateDate(dateOfK.get(Calendar.YEAR), dateOfK.get(Calendar.MONTH), dateOfK.get(Calendar.DAY_OF_MONTH) ); /** Allow complete of {@link android.widget.DatePicker.OnDateChangedListener} */ isAllowReturnToSelect = true; }