Принимая тяжелые вычисления от Android UI Thread
В моем приложении для 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 ответа
Просто чтобы немного расширить комментарий Марека Себеры, вот структура того, как вы могли бы сделать это в 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();
В дополнение к ответу Марвина на сайте разработчиков Android есть хорошая статья именно об этом.
Это не правильный способ начать поток. Вам нужно сделать:
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();
}
}
Когда я хочу использовать потоки, у меня почти большой цикл. Я ставлю логическое условие, которое всегда верно, кроме случаев, когда я хочу остановить это.
Я использую 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.