如何处理Android Kotlin Apps中的大数量?

时间:2017-11-01 09:26:31

标签: android kotlin

我有一个简单的Android应用程序,可以计算数字的阶乘。问题是每当我输入一个大于5位的数字时,app就会停止。

logcat的:

Skipped 32 frames!  The application may be doing too much work on its main thread. Background concurrent copying GC freed 131318(3MB) AllocSpace objects, 0(0B) LOS objects, 49% free, 4MB/8MB, paused 80us total 194.279ms

Kotlin代码:

package com.example.paciu.factorial

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import java.math.BigInteger


class MainActivity : AppCompatActivity() {

tailrec fun tail_recursion_factorial(n: BigInteger, factorialOfN: BigInteger = BigInteger.valueOf(2)): BigInteger {
    return when (n) {
        BigInteger.ZERO -> BigInteger.ONE
        BigInteger.ONE -> BigInteger.ONE
        BigInteger.valueOf(2) -> factorialOfN
        else -> {
            tail_recursion_factorial(n.minus(BigInteger.ONE), n.times(factorialOfN))
        }
    }
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    btnFact.setOnClickListener {
        var n = editText.text.toString()
        try {
            when {
                BigInteger(n) < BigInteger.ZERO -> textView.text = "Sorry bro! Can't do a factorial to a negative number."
                BigInteger(n) >= BigInteger.ZERO -> {
                    textView.text = "$n! is ${tail_recursion_factorial(BigInteger(n))}"
                    System.gc()

                }
            }
        } catch (e: NumberFormatException) {
            textView.text = "Sorry bro! Can't do that ..."
            }
        }
    }
}

我是这个领域的新手,所以任何人都可以帮助我理解为什么会这样吗?

2 个答案:

答案 0 :(得分:0)

您的代码在用户界面thread上运行,并且您的代码可能会花费时间限制在那个没有返回系统的情况下运行。您的代码超出了这个限制,因此您的应用程序被视为停顿并被系统杀死,因为使用“应用程序无响应”对话框。为了防止这种情况,您必须将计算移动到单独的线程,即。使用Kotlin's coroutinesAsyncTask左右。

一般来说,您需要阅读Keeping Your App Responsive及相关文档章节。

答案 1 :(得分:0)

您的消息可能不是实际错误,但请清楚说明原因。

所谓的UI-Thread用于将帧渲染到显示器。如果你正在做大量的工作,你就会阻止这种渲染并停止你的应用。

因此,不必在UI-Thread上执行所有操作,而是必须在不同的线程上安排工作,并将UI更新传递回UI-Thread。

有不同的可能模式来实现。

只是看看并自己尝试一下。您只需要知道只更新UI-Thread上的视图属性。否则你会再次以不同的理由崩溃。