私が作成しているクイズアプリのsymja androidライブラリを使って数学的計算を行っています。すべての計算は、 "1 + 3 +(4/2)"のような文字列をExprEvaluator()というライブラリ内のクラスに渡すことによって実行されます。私は私のクイズアプリを実行して、最初に質問に答えるときに使用例が私のAndroidアプリの最初の計算が遅いのはなぜですか?
ExprEvaluator().evaluate("1+3 + (4/2)") //Kotlin
だろう、それは計算を実行した場合と同様に、メインUIスレッドは凍結するだろうが、それ以降のすべての計算が非常に速くなります。以下では、問題を解決するために試した一連の戦略を概説しました。注意:私はダガーでExprEvaluatorクラスを注入してきた、それは戦略1シングルトン
class ChallengeUtils {
@Inject lateinit var exprEvaluator: ExprEvaluator
...
fun evaluate(expression: String?): IExpr? {
try {
return exprEvaluator.evaluate(expression)
} catch (e: Exception) {
throw (e)
}
}
として存在する:別々のスレッド 結果に計算をオフロード:初期計算時間の違いを作り、実際には至らなかったのより多くの問題では、私はメインのUIスレッドで結果が必要だったので。その後の計算はすべて通常どおり高速でした。
戦略2:SplashScreenアクティビティで簡単な初期計算を実行します。 結果:これは私が見つけた最良の解決策ですが、唯一の欠点は、私のスプラッシュ画面が長すぎることです。メインアプリの中に入ると、クイズはとてもうまくいく。
戦略3:スプラッシュ画面アクティビティ内の新しいスレッドで実行 結果:スプラッシュ画面の読み込みに時間がかかりすぎますが、メインスレッドで質問に回答し、他のスレッドの初期計算が完了すると、UIスレッドがフリーズします。
は、私が最初の呼び出しは、どんなに私が渡した文字列が。私は「1」に渡すことができ、常に遅くなる評価し、それ以降のすべてのより複雑な評価を取る一方で、評価が約4秒を取ることに気づきましたたかだか1ミリ秒。私はそうのように、すべてのsincle計算にExprEvaluatorクラスの新しいインスタンスを使用している場合でも:
fun evaluate(expression: String?): IExpr? {
try {
return ExprEvaluator().evaluate(expression)
} catch (e: Exception) {
throw (e)
}
私はまだ超高速です評価するために、低速初期計算し、すべてのsubsquentのコールを取得します。私はここで何が起こっているのか分かりません。それは、後のすべての計算がスムーズになるためには、重い計算が少なくとも1回は実行される必要がある、ネイティブアンドロイドの問題かどうか疑問です。
可能なリークまたはスムースを見つけるためにsystrace/memoryダンプを使用する –