2016-04-14 22 views
2

recyclerviewがビューをバインドするたびに関数を実行します。これは本当に長い操作なので、UIスレッドから離しておく必要があります。私はスレッドを作成する方法を知っていますが、特定の関数が実行されるたびに新しいスレッドを作成せずに、同じスレッドを使用して2番目のスレッドで常にonBindViewHolderメソッドのコンテンツを実行する方法はありますか?UIスレッドから特定の種類のタスクを実行するにはどうすればよいですか?

@Override 
public void onBindViewHolder (final Adapter adapter, RecyclerView.ViewHolder holder, final int position) { 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      theMethod(adapter, holder, position); 
     } 
    }).start(); 
} 
+0

あなたは "1毎回作成することなく、第2のスレッド上で実行する" 手の込んだことができますか? – Pooya

+1

私は間違っている場合は私を修正しますが、onBindViewHolderは複数回呼び出されるため、OPは同じスレッドでコードのすべてのインスタンスを実行し、毎回新しいインスタンスを作成しないようにしたいと考えています。 –

+3

'ExecutorService。 newSingleThreadExecutor'をスレッド管理に使用できます。しかし、私はこのアプローチについて懸念しています。なぜ、あなたは 'onBindViewHolder'メソッドでスレッドを行う必要がありますか?いくつかのポジションのホルダーへの参照は、スクロールのために終了したタスクの後に有効ではないことを覚えておく必要があります。 – jakubbialkowski

答えて

1

はその後HandlerThreadのLooperで作成Handlerとそのスレッドに対する作業をスケジュール、HandlerThreadを使用することを検討してください。もちろん、アクティビティの終わりにスレッドをシャットダウンすることを覚えておく必要があります。そうしないと、無限に固執してオブジェクトが漏れることがあります。例えば

:コードの

HandlerThread thread = new HandlerThread("Give Me a Name"); 
thread.start(); 
Looper looper = thread.getLooper(); 
Handler handler = new Handler(mServiceLooper); 
// use handler to post work to the thread 

これらの行は、サービスを除いて、正確にあなたが望む同じことをしている、IntentServiceから直接cribbedされています。たぶんそれはあなたが実際に使いたいものさえあります!

1

Looperを使用すると実現できます。 Looperの主な目的は、スレッドを生かして新しいメッセージ(Runnables)を待つことだけです。ここで

は、公式ドキュメントからのサンプルコードです:今

class LooperThread extends Thread { 
    public Handler mHandler; 

    public void run() { 
     Looper.prepare(); 

     mHandler = new Handler() { 
      public void handleMessage(Message msg) { 
       // process incoming messages here 
      } 
     }; 

     Looper.loop(); 
    } 

}

、あなたはハンドラを使用してスレッドに新しいランナブル(メッセージ)を投稿することができます。このような何か:

handler.post(new Runnable() 
{ 
    public void run() { 
    //This will be executed on thread using Looper. 
} 
}); 

編集:

上記の方法は、「日曜大工」をより多くのです。あなたのために自動的にこれを行うことができる、アンドロイドには特別なクラスがあります(HandlerThread)。サンプルコード:

HandlerThread thread = new HandlerThread("name"); 
thread.start(); 
Looper looper = thread.getLooper(); 
Handler handler = new Handler(looper); 

これで、このハンドラにランナブルを送信できます。

1

キューを持つジョブを実行できる新しいスレッドを作成します。

class YourThread extends Thread { 
     public List<Job> queue = new ArrayList<>(); 

     @Override 
     public void run(){ 
      while(queue.size() == 0) 
       wait(); // nothing to do, wait... 
      Job job = queue.get(queue.size() - 1); // pop queue 
      queue.remove(queue.size() - 1); 
      dosomething(job); 

     } 

     public void addJob(....){ 
      ... 
      queue.add(job, 0); 
     } 
} 

onBindViewHolder

YourThread thread = new ... 
thread.start() 

@Override 
public void onBindViewHolder (final Adapter adapter, RecyclerView.ViewHolder holder, final int position) { 
    thread.addJob(...); 
    // remember that after the job finished, the item may be recycled 
} 
関連する問題