web-dev-qa-db-ja.com

AndroidではrunOnUiThreadをどのように使用しますか?

私はAndroidの初心者で、UI-Threadを使おうとしているので、簡単なテストアクティビティを書きました。ボタンをクリックするとアプリが反応しなくなるため、誤解したと思います。

public class TestActivity extends Activity {

    Button btn;
    int i = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = (Button)findViewById(R.id.btn);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                runThread();
            }
        });
    }

    private void runThread(){
        runOnUiThread (new Thread(new Runnable() {  
            public void run() {
                while(i++ < 1000){
                    btn.setText("#"+i);
                    try {
                        Thread.sleep(300);
                    } 
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
             }
        }));
    }
}
139
user1049280

以下はrunThread関数の抜粋です。

private void runThread() {

    new Thread() {
        public void run() {
            while (i++ < 1000) {
                try {
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            btn.setText("#" + i);
                        }
                    });
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }.start();
}
191
Vipul Shah

それを関数としてラップしてから、バックグラウンドスレッドからこの関数を呼び出します。

public void debugMsg(String msg) {
    final String str = msg;
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mInfo.setText(str);
        }
    });
}
78
user4284784

あなたはそれを前後に持っています。ボタンをクリックするとrunOnUiThread()が呼び出されますが、クリックハンドラは既にUIスレッド上で実行されているため、これは必要ありません。それから、runOnUiThread()内のコードは新しいバックグラウンドスレッドを起動しています。そこで、UI操作を実行しようとしますが、失敗します。

代わりに、クリックハンドラから直接バックグラウンドスレッドを起動してください。次に、btn.setText()への呼び出しの内側にrunOnUiThread()への呼び出しをラップします。

26
Graham Borland
runOnUiThread(new Runnable() {
                public void run() {
                //Do something on UiThread
            }
        });
10
Terranology

RunOnUiThread()の使用方法はいくつかありますが、全部見てみましょう。

これはAndroidBasicThreadActivityと呼ばれる私のメインスレッド(UIスレッド)で、さまざまな方法でワーカースレッドから更新します -

public class AndroidBasicThreadActivity extends AppCompatActivity
{
    public static TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_Android_basic_thread);

        textView = (TextView) findViewById(R.id.textview);

        MyAndroidThread myTask = new MyAndroidThread(AndroidBasicThreadActivity.this);
        Thread t1 = new Thread(myTask, "Bajrang");
        t1.start();
    }
}

1)WorkerスレッドにActivityのインスタンスを引数として渡すことで

class MyAndroidThread implements Runnable
{
    Activity activity;
    public MyAndroidThread(Activity activity)
    {
        this.activity = activity;
    }
    @Override
    public void run()
    {

        //perform heavy task here and finally update the UI with result this way - 
        activity.runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
            }
        });
    }
}

2.)ワーカースレッドでViewのpost(Runnable runnable)メソッドを使用する

class MyAndroidThread implements Runnable
{
    Activity activity;
    public MyAndroidThread(Activity activity)
    {
        this.activity = activity;
    }
    @Override
    public void run()
    {
     //perform heavy task here and finally update the UI with result this way - 
       AndroidBasicThreadActivity.textView.post(new Runnable()
      { 
        @Override
        public void run()
        {
            AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
        }
    });

    }
}

3。)Android.osパッケージのHandlerクラスを使用することでコンテキスト(this/getApplicationContext())またはアクティビティのインスタンス(AndroidBasicThreadActivity)がない場合.this)それから、以下のようにHandlerクラスを使う必要があります -

class MyAndroidThread implements Runnable
{
    Activity activity;
    public MyAndroidThread(Activity activity)
    {
        this.activity = activity;
    }
    @Override
   public void run()
  {
  //perform heavy task here and finally update the UI with result this way - 
  new Handler(Looper.getMainLooper()).post(new Runnable() {
        public void run() {
            AndroidBasicThreadActivity.textView.setText("Hello!! Android Team :-) From child thread.");
        }
    });
  }
}
8
Bajrang Hudda

フラグメントで使用する場合は、単純に書く

getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
            //Do something on UiThread
        }
    });
2
Shivam Yadav

これ:

@UiThread
    public void logMsg(final String msg) {
        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                Log.d("UI thread", "I am the UI thread");


            }
        });
    }
1
MrG
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        gifImageView = (GifImageView) findViewById(R.id.GifImageView);
        gifImageView.setGifImageResource(R.drawable.success1);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //dummy delay for 2 second
                    Thread.sleep(8000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //update ui on UI thread
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        gifImageView.setGifImageResource(R.drawable.success);
                    }
                });

            }
        }).start();

    }
0
Keshav Gera

これは私がそれを使用する方法です:

runOnUiThread(new Runnable() {
                @Override
                public void run() {
                //Do something on UiThread
            }
        });
0
Josh Aquino

このサンプルから使用できます。

次の例では、この機能を使用して、バックグラウンドスレッドによって処理された同義語検索の結果を公開します。

OnCreateアクティビティのコールバック中に目標を達成するために、作成したスレッドでsearchTaskを実行するようにonClickListenerを設定します。

ユーザーが[検索]ボタンをクリックすると、R.id.wordEt EditTextに入力されたWordを検索してRunnableを実行するスレッドを開始するRunnable匿名クラスが作成されます。

検索が完了したら、Runnable SetSynonymResultのインスタンスを作成して、UIスレッドを介してシノニムTextViewに結果を公開します。

この手法は、特にActivityインスタンスにアクセスできない場合は特に便利ではありません。したがって、以降の章では、バックグラウンドコンピューティングタスクからUIを更新するための、よりシンプルでクリーンなテクニックについて説明します。

public class MainActivity extends AppCompatActivity {

    class SetSynonymResult implements Runnable {
        String synonym;

        SetSynonymResult(String synonym) {
            this.synonym = synonym;
        }

        public void run() {
            Log.d("AsyncAndroid", String.format("Sending synonym result %s on %d",
                    synonym, Thread.currentThread().getId()) + " !");
            TextView tv = (TextView) findViewById(R.id.synonymTv);
            tv.setText(this.synonym);
        }
    }

    ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button search = (Button) findViewById(R.id.searchBut);
        final EditText Word = (EditText) findViewById(R.id.wordEt);
        search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Runnable searchTask = new Runnable() {
                    @Override
                    public void run() {
                        String result = searchSynomim(Word.getText().toString());
                        Log.d("AsyncAndroid", String.format("Searching for synonym for %s on %s",
                                Word.getText(), Thread.currentThread().getName()));
                        runOnUiThread(new SetSynonymResult(result));
                    }
                };
                Thread thread = new Thread(searchTask);
                thread.start();
            }
        });

    }

    static int i = 0;

    String searchSynomim(String Word) {
        return ++i % 2 == 0 ? "fake" : "mock";
    }
}

出典

非同期AndroidプログラミングHelder Vasconcelos

0
user4813855