Страница 3 из 3

Re: Урок 80. Handler. Немного теории. Наглядный пример испо

Добавлено: 15 окт 2014, 15:27
elron
Если например хендлер создать в новом потоке поток2 и передать ему сообщение из потока3, то хендлер будет выполнять команды из потока2 ?!

Re: Урок 80. Handler. Немного теории. Наглядный пример испо

Добавлено: 06 июл 2015, 12:28
Bulvasaur
Добрый день!
Немного не понятно почему зависает приложение, когда начинает "закачивать" файлы? Вот оно заходит в цикл
for (int i = 1; i <= 10; i++)
потом одну секунду выполняет метод
// долгий процесс
downloadFile();
но потом-то должно выполнится это
// обновляем TextView
tvInfo.setText("Закачано файлов: " + i);
А оно не выполняется, а только пишется в лог. Почему основной процесс остается занятым, если он уже однократно выполнил downloadFile();
То есть, насколько я понимаю, только в течение одной секунды основной поток занят, а потом возникает возможность прорисовать экран, но этого не происходит, потому что поток чем-то занят. Так чем он получается занят?
Растолкуйте, пожалуйста.

Re: Урок 80. Handler. Немного теории. Наглядный пример испо

Добавлено: 06 июл 2015, 15:48
doter.ua
Bulvasaur писал(а):Добрый день!
Немного не понятно почему зависает приложение, когда начинает "закачивать" файлы? Вот оно заходит в цикл
for (int i = 1; i <= 10; i++)
потом одну секунду выполняет метод
// долгий процесс
downloadFile();
но потом-то должно выполнится это
// обновляем TextView
tvInfo.setText("Закачано файлов: " + i);
А оно не выполняется, а только пишется в лог. Почему основной процесс остается занятым, если он уже однократно выполнил downloadFile();
То есть, насколько я понимаю, только в течение одной секунды основной поток занят, а потом возникает возможность прорисовать экран, но этого не происходит, потому что поток чем-то занят. Так чем он получается занят?
Растолкуйте, пожалуйста.
Какая еще возможность? это все один мейн поток, код выполняется последовательно. Параллельность возникает между разными потоками.

Re: Урок 80. Handler. Немного теории. Наглядный пример испо

Добавлено: 06 июл 2015, 16:08
Bulvasaur
doter.ua писал(а):Какая еще возможность? это все один мейн поток, код выполняется последовательно. Параллельность возникает между разными потоками.
Понятно, что код выполняется последовательно. Это и не понятно)
1-й шаг цикла: выполнился downloadFile();
Следующий шаг цикла: можно выполнить tvInfo.setText("Закачано файлов: " + i); - этого не происходит. Почему? Чем конкретно занят основной поток?
Если он занят циклом

for (int i = 1; i <= 10; i++) {
// долгий процесс
downloadFile();
// обновляем TextView
tvInfo.setText("Закачано файлов: " + i);
// пишем лог
Log.d(LOG_TAG, "Закачано файлов: " + i);
}

то что ему мешает обновить вью о количестве закачанных файлов?
Или тут получается, типа: "Я занят закачкой файлов и не могу разорваться".
То есть основной поток выполняет downloadFile(); потом пропускает tvInfo.setText(); потому что занят и не может снизойти до вывода на экран, а затем выводит сообщение в лог, на которое у него ресурсы есть. То есть основной поток может производить любые расчеты, но не может их совмещать с выводом чего-либо на экран? Правильно я понимаю?

То есть если я напишу что-то подобное:

int j=0;
for (int i=0; i<10; i++) {
j=i+5;
tvInfo.setText(j);
Log.d(LOG_TAG, "j= "+j);
Tread.sleep(1000);
}

то приложение зависнет на 10 секунд, выведутся только сообщения в лог, а вью так ни разу и не обновится?
То есть один отдельно взятый поток может либо что-то рассчитывать, либо что-то делать с экраном? А согласует их действия хэндлер?

Я, вероятно, какой-то совсем тупой вопрос задаю, но иначе мне не разобраться. Извините.

Re: Урок 80. Handler. Немного теории. Наглядный пример испо

Добавлено: 06 июл 2015, 17:36
doter.ua
[quote="Bulvasaur"][/quote]

Не вырывай код из контекста, в уроке кроме цикла есть еще
Thread t = new Thread(new Runnable() {
public void run() {
это как раз отдельный поток, который не сможет менять вью т.к. они остались в другом потоке. А вот хендлер может это делать с помощью msg.

ЗЫ в уроке специально показали плохой пример, дальше будет решение.

Re: Урок 80. Handler. Немного теории. Наглядный пример испо

Добавлено: 07 июл 2015, 14:27
Bulvasaur
Ok. Задам вполне конкретный вопрос. Почему это tvInfo.setText("Закачано файлов: " + i); не может быть выполнено после этого downloadFile();? Ведь в данный конкретный момент перехода от одной строчки кода к следующей поток не занят. Или занят? Чем?

Re: Урок 80. Handler. Немного теории. Наглядный пример испо

Добавлено: 07 июл 2015, 15:41
klblk
Bulvasaur писал(а):Ok. Задам вполне конкретный вопрос. Почему это tvInfo.setText("Закачано файлов: " + i); не может быть выполнено после этого downloadFile();? Ведь в данный конкретный момент перехода от одной строчки кода к следующей поток не занят. Или занят? Чем?
Нужно глубоко покопаться в исходниках, чтобы понять всю суть. Но думаю просто View прорисовывается не сразу в ходе выполнения метода onClick() (ну и любого другого метода из ui потока), т.к. во время метода вы можете поменять кучу разных view, и при каждом таком изменении "рисовать" будет накладно.
Примерно так: Отработал метод onClick(), система проверила нужно или нет обновлять view, и если нужно обновляет.

Re: Урок 80. Handler. Немного теории. Наглядный пример испо

Добавлено: 07 июл 2015, 16:27
Bulvasaur
klblk писал(а):Нужно глубоко покопаться в исходниках, чтобы понять всю суть. Но думаю просто View прорисовывается не сразу в ходе выполнения метода onClick() (ну и любого другого метода из ui потока), т.к. во время метода вы можете поменять кучу разных view, и при каждом таком изменении "рисовать" будет накладно.
Примерно так: Отработал метод onClick(), система проверила нужно или нет обновлять view, и если нужно обновляет.
Спасибо. Что-то зашевелилось в голове. Не спроста этот хэндлер, в общем.

Re: Урок 80. Handler. Немного теории. Наглядный пример испо

Добавлено: 08 июл 2015, 20:40
burnix
в АS может возникнуть проблема при автоматическом импорте Handler. Метод sendEmptyMessage() может быть "cannot resolved", то есть покраснеть как целомудренная девушка при виде порно. Проблема решается ручной заменой импорта java.util.logging.Handler на android.os.Handler.

Re: Урок 80. Handler. Немного теории. Наглядный пример испо

Добавлено: 30 янв 2016, 13:15
0800009
Мне немного помог понять потоки и хендлер такой пример,
а именно то что вызывая один и тот же метод runLongProcess
из разных потоков мы получаем различные результаты.

Код: Выделить всё

public class MainActivity extends Activity {

	 private Button clickBtn;
	 private Button clickBtn2;
	    private ProgressDialog progressDialog;
	 
	    private Handler handler = new Handler() {
	 
	        @Override
	        public void handleMessage(Message msg) {
	            super.handleMessage(msg);
	            progressDialog.dismiss();
	           
	        }
	    };
	@Override
	protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.VERTICAL);
 
        clickBtn = new Button(this);
        clickBtn2=new Button(this);
        ll.addView(clickBtn);
        ll.addView(clickBtn2);
        
        clickBtn.setText("Click me");
        
        clickBtn.setOnClickListener(new OnClickListener() {
 
            @Override
            public void onClick(View v) {
                processThread();
            }
        });
 
        setContentView(ll);
       
    
	 clickBtn2.setOnClickListener(new OnClickListener() {
		 
         @Override
         public void onClick(View v) {
       runLongProcess();
         }
     });

    
 }
	 private void processThread() {
	        progressDialog = ProgressDialog.show(MainActivity.this, "Wait", "Running loooong process...");
	 
	        new Thread() {
	            public void run() {
	                runLongProcess();
	                handler.sendEmptyMessage(2);
	               
	            }
	        }.start();
	    }
	 private void runLongProcess() {
		 
	     try {
	            Thread.sleep(5*1000);
	            Log.e("MainActivity", "LongProcess");
	            clickBtn2.setText("Click me");
	        } catch (InterruptedException e) {
	            Log.e("MainActivity", e.getMessage());
	        }
	    }


Re: Урок 80. Handler. Немного теории. Наглядный пример испо

Добавлено: 06 фев 2016, 13:30
WKBAPKA
В Android Studio не получается получить ошибку. нажимаю на старт, на секунду замирает и дальше себе крутиться. но в логи ничего не выводит.
это особенность эмулятора?

и еще вопрос. При создании нового потока, при создании объекта Runnable() студио автоматически подставил метод Run() с ключевым словом @overide
убрал, ничего не поменялось в выполнении метода. Насколько я понимаю, это означает, что мы переопределяем метод... запутался совсем...

ПЫ СЫ: проверил на телефоне. тоже самое, ошибку не выдает

Код: Выделить всё

package consulting.brick.wkbapka.p0801_handler;

import android.app.Activity;
import android.util.Log;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.TextView;
import android.view.View;


import java.util.concurrent.TimeUnit;

public class MainActivity extends Activity {
    final String LOG_TAG = "myLog";
    Handler h;
    TextView tvInfo;
    Button btnStart;


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

        tvInfo = (TextView) findViewById(R.id.tvInfo);

    }

    public void onСlick(View v) {
        switch (v.getId()) {
            case R.id.btnStart:
                Thread t = new Thread(new Runnable() {

                    public void run() {
                        for (int i = 1; i <= 10; i++) {
                            downloadFile();
                            tvInfo.setText("Закачано файлов " + i);
                            Log.d(LOG_TAG, "Закачано файлов " + i);
                        }
                    }
                });

                break;

            case R.id.btnTest:
                Log.d(LOG_TAG,"test");
                break;
            default:
                break;
        }

    }

    void downloadFile() {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();

        }


    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

все, вопрос снят, забыл запустить поток


Добавлено: 27 ноя 2018, 11:54
levgilman
Вариант с тредом, где должно выбивать, у меня нормально работает, пишет на экране.

Re: Урок 80. Handler. Немного теории. Наглядный пример использования

Добавлено: 19 дек 2019, 14:55
alaya
Видимо в последних версиях что-то изменилось, работает как и с Thread, так и с Handler.