Принимая тяжелые вычисления от Android UI Thread - PullRequest
7 голосов
/ 01 января 2012

В моем приложении для Android используются особенно большие вычисления, которые продолжают сбивать систему, поскольку она находится в потоке пользовательского интерфейса в Activity. У меня мало уверенности в многопоточности, поэтому я хочу получить несколько советов о том, как сделать это правильно. Это то, что у меня есть

class ActivtyName extends Activity{
boolean threadcomplete = false;

 public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//stuff

Runnable newthread = new Runnable(){

            @Override
            public void run() {
                doBigComputation();
                threadcomplete=true;
            }

        };

        newthread.run();

        boolean b = true;
        while(b){
            if(threadcomplete){
                b=false;
                startTheApp();
            }
        }

}
}

Теперь я почти уверен, что то, что я сделал, не "правильно". (Кажется, работает, хотя. Система не терпит крах). По сути, я не уверен, как поток пользовательского интерфейса может сказать, что newthread завершил вычисления без этого логического, threadcomplete. Есть ли «правильный» способ сделать это?

Ответы [ 4 ]

12 голосов
/ 01 января 2012

Просто чтобы немного расширить комментарий Марека Себеры, вот структура того, как вы могли бы сделать это в AsyncTask.

private class BigComputationTask extends AsyncTask<Void, Void, Void> {

  @Override
  protected void onPreExecute() {
    // Runs on UI thread
    Log.d(TAG, "About to start...");
  }

  @Override
  protected Void doInBackground(Void... params) {
    // Runs on the background thread
    doBigComputation();
  }

  @Override
  protected void onPostExecute(Void res) {
    // Runs on the UI thread
    Log.d(TAG, "Big computation finished");
    startTheApp();
  }

}

И назвать это:

BigComputationTask t = new BigComputationTask();
t.execute();
2 голосов
/ 01 января 2012

В дополнение к ответу Марвина на сайте разработчиков Android есть хорошая статья именно об этом.

1 голос
/ 02 января 2012

Это не правильный способ начать поток.Вам нужно сделать:

    Runnable newthread = new Runnable(){

        @Override
        public void run() {
            doBigComputation();
            threadcomplete=true;
        }

    };

    Thread t = new Thread(newthread);
    newthread.start();

    boolean b = true;
    while(b){
        if(threadcomplete){
            b=false;
            startTheApp();
        }
    }
0 голосов
/ 01 января 2012

Когда я хочу использовать потоки, у меня почти большой цикл while. Я поставил логическое условие, которое всегда верно, кроме случаев, когда я хочу остановить его.

Я использую Thread (http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html)) и переопределяю метод stop, потому что он устарел. Поэтому в моем методе stop я могу поставить ложное значение в переменной цикла.

Чтобы прекратить поток, я использую t.stop (). Так что вы можете сделать это в своей деятельности.

Если вы хотите знать, когда Thead останавливается, вы можете использовать t.isAlive (). Если поток t запущен, isAlive вернет true.

...