AndroidアプリケーションのUIスレッドでは、ナノ秒または永遠に完了するためのメソッドを実行する必要があります。私はいつそれが永遠にかかるのかを正確に判断できないと思うので、私はプールを通して別のスレッドで実行しています。java/androidスレッドのlong、non-interrumpibleメソッドに代わるもの
説明のために、私はUIを1秒間ブロックしてから、メソッドが終了していない場合は移動します。
try{
Result result = futureResult.get(1, TimeUnit.SECONDS);
//Use result here
}catch(TimeoutException e) {//Other Exceptions are ommited
futureResult.cancel(true);
Log.d("DEMO", "Method takes too long. Skip");
}
私は将来をキャンセルしてfutureResult.cancel(true)
でそのスレッドを中断しようとしたが、dangerousMethod()
は中断に反応しないので、それは最終的にそのタスクを完了するまでスレッドが実行し続けます。
:ThreadPoolExecutor
をサブクラス化し、いずれかのstop()
(動作していないUnsupportedOperationException
ため)またはstop0()
(非作業(バッドプラクティスTM)を強制的に反射(ThreadPoolExecutor$Worker.thread
)を通じて民間Thread
Sを得るためNoSuchMethodException
)。これについての詳細:
class MyPool extends ThreadPoolExecutor{
//constructor, reflection code to get the Threads, etc
void cancelThread(Thread thread){
try {
thread.stop();
}catch(SecurityException | UnsupportedOperationException e) {
try {
Method stopMethod = Thread.class.getDeclaredMethod("stop0", Object.class);
stopMethod.setAccessible(true);
stopMethod.invoke(thread, new ThreadDeath());
}catch(NoSuchMethodException |
InvocationTargetException |
IllegalAccessException x)
{
Log.d("MyPool", "Can't stop thread", x);
}
}
}
}
危険なメソッドは次のように実際にある:
BigDecimal n1 = new BigDecimal("1E1000000");
BigDecimal n2 = new BigDecimal("1");
BigDecimal result = n1.add(n2);//Takes too long
私はそれがうまく扱う数字のために使用し、すべてのBigDecimal方法を確認することができますが、私が最初に知りたいのですが私は明白な何かを見逃しているか、別のアプローチがあります。だから
BigDecimal n3 = new BigDecimal("1E999999");
BigDecimal result = n1.add(n3);
がうまくいきます。
これは私が今やっていることです。低い優先度で単独でスレッドを放棄します。しかし、私は何のためにも1 CPUコアを使用する責任があると感じています。 – Civyshk
あなたは完全に正しいです - それはあなたの責任です。そして、無駄なスレッドを殺すことができないのは本当に残念です...しかし最後に、あなたの最も重要な責任は、あなたのアプリを反応させることです。 –
が承認されました。私は最後にスレッドを単独で実行させましたが、使用されていないときにActivity.onStop()でアラームを設定してアプリを強制終了します。それが私がスレッドを殺す方法です。 – Civyshk