2017-08-02 1 views
0

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); 

がうまくいきます。

答えて

0

AndroidのJavaスレッドを強制的に停止することはできないようです.Oracle Javaでは実際にはまだ動作しています。その理由は、Oracle Javaではstop()stop1()を呼び出す一方、Androidではstop(new ThreadDeath())が無条件にUnsupportedOperationExceptionをスローします。

しかし、なぜそれを強制的に強制停止しますか?それをバックグラウンドで実行させて、それを忘れて、続けてください。確かにメモリとCPUをぶつける危険がありますが、数値の一部だけがこのメソッドを長く実行すると言っているので、このスレッドを忘れる可能性があり、他のほとんどのスレッドを開始する可能性があります。

実行中のバックグラウンドスレッドが終了した後にアクションを実行しようとすると、シャットダウンするように指示するフラグを設定できます。あなたがその結果を必要としない限り、あなたは良いです。

+0

これは私が今やっていることです。低い優先度で単独でスレッドを放棄します。しかし、私は何のためにも1 CPUコアを使用する責任があると感じています。 – Civyshk

+0

あなたは完全に正しいです - それはあなたの責任です。そして、無駄なスレッドを殺すことができないのは本当に残念です...しかし最後に、あなたの最も重要な責任は、あなたのアプリを反応させることです。 –

+0

が承認されました。私は最後にスレッドを単独で実行させましたが、使用されていないときにActivity.onStop()でアラームを設定してアプリを強制終了します。それが私がスレッドを殺す方法です。 – Civyshk

関連する問題