поток Android запускается только один раз

#android #multithreading

#Android #многопоточность

Вопрос:

Я просто хотел протестировать Log.i() и посмотреть на консоль в Android Studio. В приведенном ниже коде onResume должен начинаться thread и run() следует записать бесконечный поток «dings» с тегом «run» на мониторе. Но метод run, по-видимому, вызывается только один раз. Почему?

 public class MainActivity extends Activity implements Runnable {
    Thread gameThread = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i("onCreate","getting started");
    }

    public void run() {
        Log.i("run","ding");
    }

    @Override
    public void onResume() {
        super.onResume();
        gameThread = new Thread(this);
        gameThread.start();
    }
}
  

Ответ №1:

Вы упускаете из виду понятие о том, что на самом деле делает потоковая обработка. Это позволяет вам запускать единицу работы асинхронно. Итак, применяются все те же обычные правила. Причина, по которой он запускается только один раз, заключается в том, что поток завершается после run() возврата. Итак, как и в любом другом методе, вы должны поместить что-то вроде

 while(true)
{
    Log.i("run","ding");
}
  

внутри run() . В идеале вам действительно следует проверить некоторое условие, чтобы при необходимости можно было выйти из потока.

Наконец, вероятно, это плохая идея иметь вашу MainActivity реализацию Runnable . Обычно хорошим стилем является наличие потока, реализованного, например, его собственным классом DingThread implements Runnable .

Ответ №2:

Вам не хватает while цикла, поэтому он запускается только один раз. Используйте приведенный ниже код. Это лучший подход к использованию концепции потока.

 public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i("onCreate","getting started");
    }

    @Override
    public void onResume() {
        super.onResume();
        startThread();// create thread obj and start
    }

    private GameThread mGameThread = null;
    private void startThread() {
        stopThread();// if thread already running stop it then create new thread  and start (for avoiding multi-threading).
        mGameThread = new GameThread();
        mGameThread.start();//start the thread.
    }

    //To stop the thread simply call this method.
    private void stopThread() {
        if(mGameThread != null) {
            mGameThread.setStop();
            mGameThread = null;
        }
    }

    private class GameThread extends Thread {
        private boolean mIsStop;// mIsStop is default false

        @Override
        public void run() {
           while (!mIsStop) {    // if mIsStop is false then only come inside loop.
               Log.i("run","ding");    //log will print
           }
        }

        public void setStop() {
            mIsStop = true;// set mIStop variable to true.
        }
    }
}