Урок 84. Handler. Обработка Runnable
Урок 84. Handler. Обработка Runnable
В этом уроке:
- работаем с Handler и Runnable
Click here to read this article!
- работаем с Handler и Runnable
Click here to read this article!
Последний раз редактировалось damager82 20 май 2017, 20:09, всего редактировалось 4 раза.
Re: Урок 84. Handler. Обработка Runnable
Тут почему-то еще не писали, буду первой 
Объясните, пожалуйста, если я выбрала прогрессбар кружком вида @android:style/Widget.ProgressBar.Large
Как мне его разместить в Layout-ах так, чтоб он был поверх всех элементов вьюшки? т.е. допустим нажали на кнопочку, пошло действие в бэкграунде, все элементы вьюшки затенились и на экране это колечко крутится.

Объясните, пожалуйста, если я выбрала прогрессбар кружком вида @android:style/Widget.ProgressBar.Large
Как мне его разместить в Layout-ах так, чтоб он был поверх всех элементов вьюшки? т.е. допустим нажали на кнопочку, пошло действие в бэкграунде, все элементы вьюшки затенились и на экране это колечко крутится.
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
Re: Урок 84. Handler. Обработка Runnable
Для этого нужно использовать ProgressDialog
Re: Урок 84. Handler. Обработка Runnable
Спасибочки!
R.id.team
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198
Re: Урок 84. Handler. Обработка Runnable
В новом (не главном UI потоке) вызываем h.post(updateProgress); где обращаемся к элементу интерфейсу Count.setProgress(cnt);
По идее это небезопасно. Или тот Runnable который мы отдали хендлеру имеет безопасный доступ к UI????
И не плохо было б добавить условие в showinfo а то хендлер продолжает сам себя вызывать:
if (cnt >= max) h.removeCallbacks(showInfo);
По идее это небезопасно. Или тот Runnable который мы отдали хендлеру имеет безопасный доступ к UI????
И не плохо было б добавить условие в showinfo а то хендлер продолжает сам себя вызывать:
if (cnt >= max) h.removeCallbacks(showInfo);
Re: Урок 84. Handler. Обработка Runnable
Вопрос знатокам в Уроке 80 сказали
а на уроке 84 изменили Активити с другого потока. А я думал тока с основного потока можно изменить Активити.
Я чтот не понимаю
- При попытке выполнить этот код (не в основном потоке) мы получили ошибку «Only the original thread that created
a view hierarchy can touch its views». Если по-русски, то «Только оригинальный поток, создавший view-
компоненты, может взаимодействовать с ними». Т.е. работа с view-компонентами доступна только из основного
потока. А новые потоки, которые мы создаем, не имеют доступа к элементам экрана
а на уроке 84 изменили Активити с другого потока. А я думал тока с основного потока можно изменить Активити.
Код: Выделить всё
Thread t = new Thread(new Runnable() {
public void run() {
try {
for (cnt = 1; cnt < max; cnt++) {
TimeUnit.MILLISECONDS.sleep(100);
// обновляем ProgressBar
h.post(updateProgress);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
// обновление ProgressBar
Runnable updateProgress = new Runnable() {
public void run() {
pbCount.setProgress(cnt);
}
};
// показ информации
Runnable showInfo = new Runnable() {
public void run() {
Log.d(LOG_TAG, "showInfo");
tvInfo.setText("Count = " + cnt);
// планирует сам себя через 1000 мсек
h.postDelayed(showInfo, 1000);
}
};
- KamiSempai
- Сообщения: 1339
- Зарегистрирован: 17 фев 2012, 21:23
- Откуда: Мордор
Re: Урок 84. Handler. Обработка Runnable
В этом уроке код выполняется не через прямой вызов, а через обработку сообщений. Handler h был создан в основном потоке, а значит все сообщения отправленные через него будут выполнены в основном потоке.behzodbek писал(а):а на уроке 84 изменили Активити с другого потока. А я думал тока с основного потока можно изменить Активити.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.
Хватит таскать макулатуру на тренировку! Используй T Note.
Re: Урок 84. Handler. Обработка Runnable
Тут путаница получается в понимании:behzodbek писал(а):а на уроке 84 изменили Активити с другого потока. А я думал тока с основного потока можно изменить Активити.
Как мы учили в java, в интерфейсе Runnable методом run() выделяется код, запускаемый в отдельном потоке. И когда мы видим такое:
Код: Выделить всё
Runnable updateProgress = new Runnable() {
public void run() {
pbCount.setProgress(cnt);
}
};
Код: Выделить всё
Runnable showInfo = new Runnable() {
public void run() {
Log.d(LOG_TAG, "showInfo");
tvInfo.setText("Count = " + cnt);
// планирует сам себя через 1000 мсек
h.postDelayed(showInfo, 1000);
}
};
Re: Урок 84. Handler. Обработка Runnable
Подскажите, почему в setAlpha alpha не меняется?
fadeOut() вызывается из Activity
Код: Выделить всё
public class ImageFragment extends Fragment {
Quiz quiz;
Handler h;
Thread t;
ScaledImageView v;
int alpha;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout view = (LinearLayout) inflater.inflate(R.layout.quizimage, null);
v = (ScaledImageView) view.findViewById(R.id.image);
v.setBackgroundDrawable(quiz.quizData.background);
v.setImageDrawable(quiz.quizData.image);
v.setAlpha(quiz.quizData.isComplete ? 254 : 0);
return view;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
quiz = (Quiz) activity;
}
public void fadeOut(ScaledImageView v) {
h = new Handler();
t = new Thread(new Runnable() {
@Override
public void run() {
try {
for (int alpha = 0; alpha < 255; alpha++) {
TimeUnit.MILLISECONDS.sleep(10);
h.post(setAlpha);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
}
Runnable setAlpha = new Runnable() {
@Override
public void run() {
Log.d("mylog", "Alpha = " + alpha);
v.setAlpha(alpha);
}
};
}
Код: Выделить всё
imageFragment.fadeOut((ScaledImageView) imageFragment.getView().findViewById(R.id.image));
Re: Урок 84. Handler. Обработка Runnable
Заменил на AsyncTask, все работает.
-
- Сообщения: 10
- Зарегистрирован: 23 авг 2013, 13:26
Re: Урок 84. Handler. Обработка Runnable
Гуру, а как остановить это Runnable?
Я дошел до урока 87 (закодил и отправил на виртуальный девайс приложения) и случайно увидел, что в логах LogCat с периодом в 1с появляются сообщения от кода этого урока. Я так понимаю, нужно принудительно завершить работу после выполнения например 100 циклов.
Я дошел до урока 87 (закодил и отправил на виртуальный девайс приложения) и случайно увидел, что в логах LogCat с периодом в 1с появляются сообщения от кода этого урока. Я так понимаю, нужно принудительно завершить работу после выполнения например 100 циклов.
Re: Урок 84. Handler. Обработка Runnable
У меня есть 2 проблемы
1)Планшет вызывает 2 раза метод OnCreate 1 раз когда создает активити потом он понимает что ему нужно его перевернуть (
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.find_a_star_activity); ...
)
У моего планшета по умолчанию отображение рабочего стола, если отключить авто поворот, ландшафт
2) Вытекает из 1-вой не могу понять, как проверить, если процесс запущен не запускать опять. Этот код в OnCreate;
Create_Thread = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Get_Info_Cursor_Honorees_FirstName();
Handler_FAS.sendEmptyMessage(VIEW_LIST);
}
});
if (Create_Thread.getState() != Thread.State.RUNNABLE && Create_Thread.isAlive() == false) {
Create_Thread.start();
}
1)Планшет вызывает 2 раза метод OnCreate 1 раз когда создает активити потом он понимает что ему нужно его перевернуть (
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.find_a_star_activity); ...
)
У моего планшета по умолчанию отображение рабочего стола, если отключить авто поворот, ландшафт
2) Вытекает из 1-вой не могу понять, как проверить, если процесс запущен не запускать опять. Этот код в OnCreate;
Create_Thread = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Get_Info_Cursor_Honorees_FirstName();
Handler_FAS.sendEmptyMessage(VIEW_LIST);
}
});
if (Create_Thread.getState() != Thread.State.RUNNABLE && Create_Thread.isAlive() == false) {
Create_Thread.start();
}
Re: Урок 84. Handler. Обработка Runnable
Если, если, например, мы создали поток.
Этот поток отправляет сообщение в основной поток. Метод updateProgress будет выполняться в основном потоке, или в созданном потоке t?
Код: Выделить всё
Thread t = new Thread(new Runnable() {
public void run() {
try {
for (cnt = 1; cnt < max; cnt++) {
TimeUnit.MILLISECONDS.sleep(100);
// обновляем ProgressBar
h.post(updateProgress);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
Re: Урок 84. Handler. Обработка Runnable
Как останавливать поток и запускать заново?
Re: Урок 84. Handler. Обработка Runnable
Добрый день!
Столкнулся с такой проблемой. Нужно при работе с WallpaperService на основе Canvas (не OpenGL) организовать Fade-эффект между двумя изображениями. И всё бы хорошо, если не были бы возможны ситуации как двойного или одинарного тапа, так и свайпа в разных направлениях во время данного эффекта. По Fade-эффекту достаточно много примеров в Интернете как на stackoverflow.com, так и в независимых источниках, но все они касаются анимации вьюшек, а никак не моего случая. Как я понимаю с вьюхами всё гараздо проще (есть реализуемый метод onDraw() и вызываемый метод invalidate()). На случай обоевой канвы в нашем распоряжении два холдеровых метода (locCanvas() и unlockCanvasAndPost()).
Чтобы сильно много не болтать, скажу суть. Для реагирования на тапы во время перехода(ни до, ни после) всю логику этого самого перехода я хотел выделить в отдельный поток, а захват и сброс канвы на экран реализовать в обработчике сообщений handleMessage(). Но при таком раскладе никакого эффекта не происходит (только мерцание изображений без плавного транспорирования).
Подскажите, пожалуйста, может кто сталкивался с такой проблемой, как здесь можно реализовать задуманное?
Простите великодушно за многобуквенность!
Заранее благодарен любым ответам!
Столкнулся с такой проблемой. Нужно при работе с WallpaperService на основе Canvas (не OpenGL) организовать Fade-эффект между двумя изображениями. И всё бы хорошо, если не были бы возможны ситуации как двойного или одинарного тапа, так и свайпа в разных направлениях во время данного эффекта. По Fade-эффекту достаточно много примеров в Интернете как на stackoverflow.com, так и в независимых источниках, но все они касаются анимации вьюшек, а никак не моего случая. Как я понимаю с вьюхами всё гараздо проще (есть реализуемый метод onDraw() и вызываемый метод invalidate()). На случай обоевой канвы в нашем распоряжении два холдеровых метода (locCanvas() и unlockCanvasAndPost()).
Чтобы сильно много не болтать, скажу суть. Для реагирования на тапы во время перехода(ни до, ни после) всю логику этого самого перехода я хотел выделить в отдельный поток, а захват и сброс канвы на экран реализовать в обработчике сообщений handleMessage(). Но при таком раскладе никакого эффекта не происходит (только мерцание изображений без плавного транспорирования).
Подскажите, пожалуйста, может кто сталкивался с такой проблемой, как здесь можно реализовать задуманное?
Код: Выделить всё
public class MyClass extends WallpaperService {
//Вспомогательный класс для передачи в хэндлер канвы и холдера
class MyObject{
private Canvas canvas = null;
private SurfaceHolder holder = null;
MyObject(SurfaceHolder sh, Canvas cv){
canvas = cv;
holder= sh;
}
public SurfaceHolder getHolder(){return holder;}
public Canvas getCanvas(){return canvas;}
}
//Хэндлер, посылающий и обрабатывающий сообщения
private final Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
MyObject myObject= (MyObject)msg.obj;
switch(msg.what){
case 1:
Canvas c = myObject.getCanvas();
c = myObject.getHolder().lockCanvas();
break;
case 2:
myObject.getHolder().unlockCanvasAndPost(myObject.getCanvas());
break;
}
}
};
//Класс рендеринга
class WallpaperEngine extends Engine implements OnSharedPreferenceChangeListener {
.........................
private final Paint mPaint = new Paint();
private boolean mVisible = false;
private Bitmap mBitmap = null;
private Bitmap mPreviousBitmap = null;
private long mLastDrawTime = 0;
private final GestureDetector doubleTapDetector;
.........................
private final Runnable mWorker = new Runnable() {
public void run() {
if (mDuration > 0)
drawFrame();
}
};
WallpaperEngine() {
.......................
doubleTapDetector = new GestureDetector(HDLiveWallpaper.this,
new SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(MotionEvent e) {
if (mTouchEvents) {
mLastDrawTime = 0;
if(myThread!=null)stopThread(myThread);
drawFrame();
return true;
}
return false;
}
}
);
}
private void stopThread(MyThread thread)
{
if( myThread != null ) myThread = null;
}
.................
.................
.................
//Метод отрисовки (привожу только более менее относящееся к вопросу)
void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
//Получаем первое или следующее изображение для отрисовки
...................
//В случае первого входа в функцию или различных манипуляция до и после эффекта
//фиксируем канву:
c = holder.lockCanvas();
...................
c.drawColor(Color.BLACK);
c.drawBitmap(mBitmap, xPos, yPos, mPaint);
...................
if (c != null){
if((mPreviousBitmap==null) || (mPreviousBitmap==mBitmap))
holder.unlockCanvasAndPost(c);
else{
if(mTransition==1){
myThread = new MyThread(holder,c);
myThread.start();
}
else
holder.unlockCanvasAndPost(c);
}
mPreviousBitmap = mBitmap;
}
....................
mHandler.removeCallbacks(mWorker);
if (mVisible/*-если мы в фореграунде*/) {
mHandler.postDelayed(mWorker, 1000 / 2); //mWorker - это Runnable, который запускает поначалу и далее выполняет метод
//drawFrame() циклически или по требованию
}
}
//Поток с Fade-эффектом
public class MyThread extends Thread{
private SurfaceHolder _surfaceHolder;
private Canvas c;
public MyThread(SurfaceHolder holder, Canvas canvas){
_surfaceHolder = holder;
c = canvas;
}
public SurfaceHolder getHolder() { return _surfaceHolder; }
public Canvas getCanvas() { return c; }
public void run(){
c.drawBitmap(mBitmap, 0, 0, mPaint);
int tmpPaintAlpha = mPaint.getAlpha();
mPaint.setAlpha(254);
c.drawBitmap(mPreviousBitmap, 0, 0, mPaint);
//Первым делом необходимо разрочить ранее(в drawFrame()) залоченную канву
MyObject myObject = new MyObject(_surfaceHolder,c);
Message msg = mHandler.obtainMessage(2, myObject);
mHandler.sendMessage(msg); //_surfaceHolder.unlockCanvasAndPost(c);
mPaint.setAlpha(tmpPaintAlpha);
int i=253;
while(i!=0){
msg = mHandler.obtainMessage(1, myObject);
mHandler.sendMessage(msg);//c = _surfaceHolder.lockCanvas();
c.drawBitmap(mBitmap, 0, 0, mPaint);
mPaint.setAlpha(i);
c.drawBitmap(mPreviousBitmap, 0, 0, mPaint);
msg = mHandler.obtainMessage(2, myObject);
mHandler.sendMessage(msg);//_surfaceHolder.unlockCanvasAndPost(c);
mPaint.setAlpha(255);
i-=1;
}
myThread = null;
}
}
}
}
Заранее благодарен любым ответам!
Последний раз редактировалось EvilAngel 02 ноя 2013, 10:19, всего редактировалось 3 раза.
Re: Урок 84. Handler. Обработка Runnable
Остановить можно простым [syntax=java5]mThread = null[/syntax], приостановить [syntax=java5]mThread.interrupt()[/syntax], а запуск обычным [syntax=java5]mThread.start()[/syntax].sensetiw писал(а):Как останавливать поток и запускать заново?
Re: Урок 84. Handler. Обработка Runnable
Думаю он всё-таки не запускается внутри основного потока, а запускается внутри потока "message queue", который и обрабатывает всё, что приходит в хендлер.alexshr писал(а): то сразу начинает мерещиться старт нового потока. Но для этого нужен вызов start(), а в вышеприведенном коде, который и работает с view, этого нет, а есть просто метод с названием run(), который и запускается внутри основного потока
-
- Сообщения: 36
- Зарегистрирован: 28 июн 2015, 03:13
Re: Урок 84. Handler. Обработка Runnable
Доброго всем дня!
Подскажите, Бывают ли случаи когда сообщение отправляется из основного потока в новые потоки? А-то в уроках все время отправляли только в основной.
Подскажите, Бывают ли случаи когда сообщение отправляется из основного потока в новые потоки? А-то в уроках все время отправляли только в основной.
-
- Сообщения: 3
- Зарегистрирован: 25 июл 2015, 09:27
Re: Урок 84. Handler. Обработка Runnable
Изменения не какие не происходили? я уже какой раз пытаюсь сделать Android Studio выдает всякую шляпу...
Вообщем все перепробывал с фрагмента запускаю код, выполняется разок в начале и все...
Может я чето не так делаю... Но в итоге мне надо у webview.loadurl сделать
Вообщем все перепробывал с фрагмента запускаю код, выполняется разок в начале и все...
Может я чето не так делаю... Но в итоге мне надо у webview.loadurl сделать
Re: Урок 84. Handler. Обработка Runnable
где в коде указано,что счетчик увеличивается каждый раз на 10?Не совсем понял как это