Skip to content

Commit 1e03cb2

Browse files
authored
Merge pull request #21 from kabirnayeem99/feat/bg_threading
Fix app freeze issue to close #14
2 parents 6a11ae1 + 9f29799 commit 1e03cb2

File tree

1 file changed

+135
-104
lines changed

1 file changed

+135
-104
lines changed

app/src/main/java/com/darkempire78/opencalculator/MainActivity.kt

Lines changed: 135 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@ import android.os.Bundle
99
import android.view.HapticFeedbackConstants
1010
import android.view.MenuItem
1111
import android.view.View
12-
import android.widget.*
12+
import android.widget.PopupMenu
1313
import androidx.appcompat.app.AppCompatActivity
14+
import androidx.lifecycle.lifecycleScope
1415
import kotlinx.android.synthetic.main.activity_main.*
16+
import kotlinx.coroutines.Dispatchers
17+
import kotlinx.coroutines.launch
18+
import kotlinx.coroutines.withContext
1519
import org.mariuszgromada.math.mxparser.Expression
1620
import org.mariuszgromada.math.mxparser.mXparser
1721

@@ -21,6 +25,7 @@ class MainActivity : AppCompatActivity() {
2125
// https://stackoverflow.com/questions/34197026/android-content-pm-applicationinfo-android-content-context-getapplicationinfo
2226
private var isInvButtonClicked = false
2327

28+
2429
override fun onCreate(savedInstanceState: Bundle?) {
2530
super.onCreate(savedInstanceState)
2631

@@ -49,8 +54,7 @@ class MainActivity : AppCompatActivity() {
4954
setTheme(R.style.amoledTheme)
5055
}
5156
// Material You
52-
3->
53-
{
57+
3 -> {
5458
if (checkIfDarkModeIsEnabledByDefault()) {
5559
setTheme(R.style.materialYouDark)
5660
} else {
@@ -74,7 +78,7 @@ class MainActivity : AppCompatActivity() {
7478

7579
// Disable the keyboard on display EditText
7680
input.showSoftInputOnFocus = false
77-
81+
7882
// https://www.geeksforgeeks.org/how-to-detect-long-press-in-android/
7983
backspaceButton.setOnLongClickListener {
8084
input.setText("")
@@ -92,7 +96,7 @@ class MainActivity : AppCompatActivity() {
9296
tableLayout.layoutTransition = lt
9397
}
9498

95-
private fun checkIfDarkModeIsEnabledByDefault (): Boolean =
99+
private fun checkIfDarkModeIsEnabledByDefault(): Boolean =
96100
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
97101
resources.configuration.isNightModeActive
98102
} else
@@ -111,7 +115,8 @@ class MainActivity : AppCompatActivity() {
111115
val popup = PopupMenu(this, view)
112116
val inflater = popup.menuInflater
113117
inflater.inflate(R.menu.app_menu, popup.menu)
114-
popup.menu.findItem(R.id.app_menu_vibration_button).isChecked = MyPreferences(this).vibrationMode;
118+
popup.menu.findItem(R.id.app_menu_vibration_button).isChecked =
119+
MyPreferences(this).vibrationMode;
115120
popup.show()
116121
}
117122

@@ -127,7 +132,7 @@ class MainActivity : AppCompatActivity() {
127132
startActivity(browserIntent)
128133
}
129134

130-
fun keyVibration(view : View) {
135+
private fun keyVibration(view: View) {
131136
if (MyPreferences(this).vibrationMode) {
132137
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
133138
view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_PRESS)
@@ -136,78 +141,96 @@ class MainActivity : AppCompatActivity() {
136141
}
137142

138143
private fun updateDisplay(view: View, value: String) {
139-
// Vibrate when key pressed
140-
keyVibration(view)
141-
142-
val formerValue = input.text.toString()
143-
val cursorPosition = input.selectionStart
144-
val leftValue = formerValue.subSequence(0, cursorPosition).toString()
145-
val rightValue = formerValue.subSequence(cursorPosition, formerValue.length).toString()
144+
lifecycleScope.launch(Dispatchers.Default) {
145+
withContext(Dispatchers.Main) {
146+
// Vibrate when key pressed
147+
keyVibration(view)
148+
}
146149

147-
val newValue = leftValue + value + rightValue
150+
val formerValue = input.text.toString()
151+
val cursorPosition = input.selectionStart
152+
val leftValue = formerValue.subSequence(0, cursorPosition).toString()
153+
val rightValue = formerValue.subSequence(cursorPosition, formerValue.length).toString()
148154

149-
// Update Display
150-
input.setText(newValue)
155+
val newValue = leftValue + value + rightValue
151156

152-
// Increase cursor position
153-
input.setSelection(cursorPosition + value.length)
157+
withContext(Dispatchers.Main) {
158+
// Update Display
159+
input.setText(newValue)
154160

155-
// Update resultDisplay
156-
updateResultDisplay()
161+
// Increase cursor position
162+
input.setSelection(cursorPosition + value.length)
163+
164+
// Update resultDisplay
165+
updateResultDisplay()
166+
}
167+
}
157168
}
158169

159170
private fun updateResultDisplay() {
160-
var calculation = input.text.toString()
171+
lifecycleScope.launch(Dispatchers.Default) {
172+
var calculation = input.text.toString()
161173

162-
if (calculation != "") {
163-
calculation = calculation.replace('×', '*')
164-
calculation = calculation.replace('÷', '/')
165-
calculation = calculation.replace("log", "log10")
174+
if (calculation != "") {
175+
calculation = calculation.replace('×', '*')
176+
calculation = calculation.replace('÷', '/')
177+
calculation = calculation.replace("log", "log10")
166178

167-
// Add ")" which lack
168-
var openParentheses = 0
169-
var closeParentheses = 0
179+
// Add ")" which lack
180+
var openParentheses = 0
181+
var closeParentheses = 0
170182

171-
for (i in 0..calculation.length-1) {
172-
if (calculation[i] == '(') {
173-
openParentheses += 1
174-
}
175-
if (calculation[i] == ')') {
176-
closeParentheses += 1
183+
for (i in 0..calculation.length - 1) {
184+
if (calculation[i] == '(') {
185+
openParentheses += 1
186+
}
187+
if (calculation[i] == ')') {
188+
closeParentheses += 1
189+
}
177190
}
178-
}
179-
if (closeParentheses < openParentheses) {
180-
for (i in 0..openParentheses-closeParentheses-1) {
181-
calculation += ')'
191+
if (closeParentheses < openParentheses) {
192+
for (i in 0..openParentheses - closeParentheses - 1) {
193+
calculation += ')'
194+
}
182195
}
183-
}
184196

185-
val exp = Expression(calculation)
186-
var result = exp.calculate().toString()
187-
188-
if (result != "NaN" && result != "Infinity") {
189-
// If the double ends with .0 we remove the .0
190-
if ((exp.calculate() * 10) % 10 == 0.0) {
191-
result = String.format("%.0f", exp.calculate())
192-
if (result != calculation) {
193-
resultDisplay.setText(result)
197+
val exp = Expression(calculation)
198+
var result = exp.calculate().toString()
199+
200+
if (result != "NaN" && result != "Infinity") {
201+
// If the double ends with .0 we remove the .0
202+
if ((exp.calculate() * 10) % 10 == 0.0) {
203+
result = String.format("%.0f", exp.calculate())
204+
withContext(Dispatchers.Main) {
205+
if (result != calculation) resultDisplay.setText(result)
206+
else resultDisplay.setText("")
207+
}
194208
} else {
195-
resultDisplay.setText("")
209+
withContext(Dispatchers.Main) {
210+
211+
if (result != calculation) {
212+
resultDisplay.setText(result)
213+
} else {
214+
resultDisplay.setText("")
215+
}
216+
}
196217
}
197-
} else {
198-
if (result != calculation) {
199-
resultDisplay.setText(result)
218+
} else withContext(Dispatchers.Main) {
219+
if (result == "Infinity") {
220+
221+
resultDisplay.setText("Infinity")
222+
200223
} else {
201-
resultDisplay.setText("")
224+
withContext(Dispatchers.Main) {
225+
resultDisplay.setText("")
226+
}
202227
}
203228
}
204-
} else if (result == "Infinity") {
205-
resultDisplay.setText("Infinity")
206229
} else {
207-
resultDisplay.setText("")
230+
withContext(Dispatchers.Main) {
231+
resultDisplay.setText("")
232+
}
208233
}
209-
} else {
210-
resultDisplay.setText("")
211234
}
212235
}
213236

@@ -393,54 +416,59 @@ class MainActivity : AppCompatActivity() {
393416
}
394417

395418
fun equalsButton(view: View) {
396-
keyVibration(view)
397419

398-
var calculation = input.text.toString()
399-
calculation = calculation.replace('×', '*')
400-
calculation = calculation.replace('÷', '/')
401-
calculation = calculation.replace("log", "log10")
420+
lifecycleScope.launch(Dispatchers.Default) {
421+
keyVibration(view)
422+
423+
var calculation = input.text.toString()
424+
calculation = calculation.replace('×', '*')
425+
calculation = calculation.replace('÷', '/')
426+
calculation = calculation.replace("log", "log10")
402427

403-
if (calculation != "") {
404-
// Add ")" which lack
405-
var openParentheses = 0
406-
var closeParentheses = 0
428+
if (calculation != "") {
429+
// Add ")" which lack
430+
var openParentheses = 0
431+
var closeParentheses = 0
407432

408-
for (i in 0..calculation.length-1) {
409-
if (calculation[i] == '(') {
410-
openParentheses += 1
411-
}
412-
if (calculation[i] == ')') {
413-
closeParentheses += 1
433+
for (i in 0..calculation.length - 1) {
434+
if (calculation[i] == '(') {
435+
openParentheses += 1
436+
}
437+
if (calculation[i] == ')') {
438+
closeParentheses += 1
439+
}
414440
}
415-
}
416-
if (closeParentheses < openParentheses) {
417-
for (i in 0..openParentheses-closeParentheses-1) {
418-
calculation += ')'
441+
if (closeParentheses < openParentheses) {
442+
for (i in 0..openParentheses - closeParentheses - 1) {
443+
calculation += ')'
444+
}
419445
}
420-
}
421446

422-
val exp = Expression(calculation)
423-
var result = exp.calculate().toString()
447+
val exp = Expression(calculation)
448+
var result = exp.calculate().toString()
449+
450+
mXparser.consolePrintln("Res: " + exp.expressionString.toString() + " = " + exp.calculate())
424451

425-
mXparser.consolePrintln("Res: " + exp.expressionString.toString() + " = " + exp.calculate())
452+
if (result != "NaN" && result != "Infinity") {
453+
if ((exp.calculate() * 10) % 10 == 0.0) {
454+
result = String.format("%.0f", exp.calculate())
455+
withContext(Dispatchers.Main) { input.setText(result) }
456+
} else {
457+
withContext(Dispatchers.Main) { input.setText(result) }
458+
}
459+
// Set cursor
460+
withContext(Dispatchers.Main) {
461+
input.setSelection(input.text.length)
426462

427-
if (result != "NaN" && result != "Infinity") {
428-
if ((exp.calculate() * 10) % 10 == 0.0) {
429-
result = String.format("%.0f", exp.calculate())
430-
input.setText(result)
463+
// Clear resultDisplay
464+
resultDisplay.setText("")
465+
}
431466
} else {
432-
input.setText(result)
467+
withContext(Dispatchers.Main) { resultDisplay.setText(result) }
433468
}
434-
// Set cursor
435-
input.setSelection(input.text.length)
436-
437-
// Clear resultDisplay
438-
resultDisplay.setText("")
439469
} else {
440-
resultDisplay.setText(result)
470+
withContext(Dispatchers.Main) { resultDisplay.setText("") }
441471
}
442-
} else {
443-
resultDisplay.setText("")
444472
}
445473
}
446474

@@ -455,7 +483,7 @@ class MainActivity : AppCompatActivity() {
455483

456484
// https://kotlinlang.org/docs/ranges.html
457485
// https://www.reddit.com/r/Kotlin/comments/couh07/getting_error_operator_cannot_be_applied_to_char/
458-
for (i in 0..cursorPosition-1) {
486+
for (i in 0..cursorPosition - 1) {
459487
if (text[i] == '(') {
460488
openParentheses += 1
461489
}
@@ -467,12 +495,14 @@ class MainActivity : AppCompatActivity() {
467495
if (openParentheses == closeParentheses || input.text.toString().subSequence(
468496
textLength - 1,
469497
textLength
470-
) == "(") {
498+
) == "("
499+
) {
471500
updateDisplay(view, "(")
472501
} else if (closeParentheses < openParentheses && input.text.toString().subSequence(
473502
textLength - 1,
474503
textLength
475-
) != "(") {
504+
) != "("
505+
) {
476506
updateDisplay(view, ")")
477507
}
478508

@@ -486,10 +516,12 @@ class MainActivity : AppCompatActivity() {
486516
val textLength = input.text.length
487517

488518
if (cursorPosition != 0 && textLength != 0) {
489-
val newValue = input.text.subSequence(0, cursorPosition - 1).toString() + input.text.subSequence(
490-
cursorPosition,
491-
textLength
492-
).toString()
519+
val newValue =
520+
input.text.subSequence(0, cursorPosition - 1)
521+
.toString() + input.text.subSequence(
522+
cursorPosition,
523+
textLength
524+
).toString()
493525
input.setText(newValue)
494526

495527
input.setSelection(cursorPosition - 1)
@@ -499,8 +531,7 @@ class MainActivity : AppCompatActivity() {
499531
}
500532

501533
fun scientistModeSwitchButton(view: View) {
502-
if(scientistModeRow2.visibility != View.VISIBLE)
503-
{
534+
if (scientistModeRow2.visibility != View.VISIBLE) {
504535
scientistModeRow2.visibility = View.VISIBLE
505536
scientistModeRow3.visibility = View.VISIBLE
506537
scientistModeSwitchButton.setImageResource(R.drawable.ic_baseline_keyboard_arrow_up_24)

0 commit comments

Comments
 (0)