-
Arssir
- Сообщения: 38
- Зарегистрирован: 09 июн 2013, 15:22
- Откуда: Москва
Сообщение
Arssir » 19 июл 2013, 13:56
Nyashka писал(а):Arssir писал(а):
GView - класс наследуемый от View
Таки есть View. У View есть метод postInvalidate() для вызова перерисовки (произойдет вызов onDraw). Код таймера приводил выше, его надо занести в код класса вьюва, а в конструктор или в onCreate занести первый вызов таймера. Возможно вы это уже и сами поняли, я только только с этим разобрался и решил поделиться =)
Вроде бы понял, но у меня опять возникли проблемы с взаимодействием между классами. В onCreate я вызываю метод GView.schedule(); А в GView такой код:
Код: Выделить всё
Timer timer;
TimerTask tTask;
//...
public void schedule(){
if (tTask != null) tTask.cancel();
tTask = new TimerTask() {
public void run() {
invalidate();
}
};
timer.schedule(tTask, 0, 100);
}
Но чтобы все заработало, нужно, чтобы метод был static, но если так сделать не работает invalidate();
Может это проблема "для нубиков", но у меня реально плохо получается понимать принципы взаимодействия разных классов в java.
-
Nyashka
- Сообщения: 40
- Зарегистрирован: 19 мар 2013, 13:06
Сообщение
Nyashka » 19 июл 2013, 17:36
Arssir писал(а):
Но чтобы все заработало, нужно, чтобы метод был static, но если так сделать не работает invalidate();
Может это проблема "для нубиков", но у меня реально плохо получается понимать принципы взаимодействия разных классов в java.
Не знаю какой тут уровень, но у invalidate() в описании указывает что она должна вызываться только из основного потока, а используя таймер ты создаешь отдельные асинхронный поток. В нем ты можешь пользоваться только postInvalidate(), который вызовет прорисовку спустя какое то время (связанное с вертикальной синхронизацией). Про статик ни чего не могу сказать
-
Arssir
- Сообщения: 38
- Зарегистрирован: 09 июн 2013, 15:22
- Откуда: Москва
Сообщение
Arssir » 19 июл 2013, 17:54
Nyashka писал(а):Arssir писал(а):
Но чтобы все заработало, нужно, чтобы метод был static, но если так сделать не работает invalidate();
Может это проблема "для нубиков", но у меня реально плохо получается понимать принципы взаимодействия разных классов в java.
Не знаю какой тут уровень, но у invalidate() в описании указывает что она должна вызываться только из основного потока, а используя таймер ты создаешь отдельные асинхронный поток. В нем ты можешь пользоваться только postInvalidate(), который вызовет прорисовку спустя какое то время (связанное с вертикальной синхронизацией). Про статик ни чего не могу сказать
c postInvalidate() тоже самое "Cannot make a static reference to the non-static method postInvalidate() from the type View"
-
Nyashka
- Сообщения: 40
- Зарегистрирован: 19 мар 2013, 13:06
Сообщение
Nyashka » 20 июл 2013, 09:41
Arssir писал(а):
c postInvalidate() тоже самое "Cannot make a static reference to the non-static method postInvalidate() from the type View"
А таймер у вас где объявлен, в Активити или во Вьюве? У Вас Вьюв в отдельном модуле находится, или прописан в том же модуле что и Активити, в самом классе Активити?
-
Arssir
- Сообщения: 38
- Зарегистрирован: 09 июн 2013, 15:22
- Откуда: Москва
Сообщение
Arssir » 20 июл 2013, 10:27
Nyashka писал(а):Arssir писал(а):
c postInvalidate() тоже самое "Cannot make a static reference to the non-static method postInvalidate() from the type View"
А таймер у вас где объявлен, в Активити или во Вьюве? У Вас Вьюв в отдельном модуле находится, или прописан в том же модуле что и Активити, в самом классе Активити?
Активити и Вьюв в разных классах расположены, из Активити только вызывается метод с таймером, расположенный во Вьюве
-
Nyashka
- Сообщения: 40
- Зарегистрирован: 19 мар 2013, 13:06
Сообщение
Nyashka » 20 июл 2013, 10:57
Arssir писал(а):Nyashka писал(а):Arssir писал(а):
c postInvalidate() тоже самое "Cannot make a static reference to the non-static method postInvalidate() from the type View"
А таймер у вас где объявлен, в Активити или во Вьюве? У Вас Вьюв в отдельном модуле находится, или прописан в том же модуле что и Активити, в самом классе Активити?
Активити и Вьюв в разных классах расположены, из Активити только вызывается метод с таймером, расположенный во Вьюве
Хм.. Не совсем понял, но попробую помочь (или еще сильнее запутать). И указатели и созданный экземпляр и планировщик(sсhedule()) должны находиться в классе Активити. Вьюв содержит только onDraw() и onTouchEvent(). В run(){} который в sсhedule() только postInvalidate(), с указанием имени класса наследованного от вьюва (MyView.postInvalidate(); для class MyView extends View{}). Есть еще вариант поместить это все во вьюв, но код с ходу прикинуть не могу
-
Arssir
- Сообщения: 38
- Зарегистрирован: 09 июн 2013, 15:22
- Откуда: Москва
Сообщение
Arssir » 20 июл 2013, 12:04
Nyashka писал(а):
Хм.. Не совсем понял, но попробую помочь (или еще сильнее запутать). И указатели и созданный экземпляр и планировщик(sсhedule()) должны находиться в классе Активити. Вьюв содержит только onDraw() и onTouchEvent(). В run(){} который в sсhedule() только postInvalidate(), с указанием имени класса наследованного от вьюва (MyView.postInvalidate(); для class MyView extends View{}). Есть еще вариант поместить это все во вьюв, но код с ходу прикинуть не могу
Попытался перевести все в Активити, теперь он выглядит так
Код: Выделить всё
public class MainActivity extends Activity {
Timer timer;
TimerTask tTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GView v = new GView(this);
setContentView(v);
schedule(); //запуск таймера
}
public void schedule(){
if (tTask != null) tTask.cancel();
tTask = new TimerTask() {
public void run() {
GView.postInvalidate();
}
};
timer.schedule(tTask, 0, 100);
}
}
но проблема все также "Cannot make a static reference to the non-static method postInvalidate() from the type View"
-
Nyashka
- Сообщения: 40
- Зарегистрирован: 19 мар 2013, 13:06
Сообщение
Nyashka » 20 июл 2013, 12:16
Arssir писал(а):Nyashka писал(а):
Хм.. Не совсем понял, но попробую помочь (или еще сильнее запутать). И указатели и созданный экземпляр и планировщик(sсhedule()) должны находиться в классе Активити. Вьюв содержит только onDraw() и onTouchEvent(). В run(){} который в sсhedule() только postInvalidate(), с указанием имени класса наследованного от вьюва (MyView.postInvalidate(); для class MyView extends View{}). Есть еще вариант поместить это все во вьюв, но код с ходу прикинуть не могу
Попытался перевести все в Активити, теперь он выглядит так
Код: Выделить всё
public class MainActivity extends Activity {
Timer timer;
TimerTask tTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GView v = new GView(this);
setContentView(v);
schedule(); //запуск таймера
}
public void schedule(){
if (tTask != null) tTask.cancel();
tTask = new TimerTask() {
public void run() {
GView.postInvalidate();
}
};
timer.schedule(tTask, 0, 100);
}
}
но проблема все также "Cannot make a static reference to the non-static method postInvalidate() from the type View"
Не вижу в onCreate() создания экземпляра Timer = new Timer(); он там есть?
-
Arssir
- Сообщения: 38
- Зарегистрирован: 09 июн 2013, 15:22
- Откуда: Москва
Сообщение
Arssir » 20 июл 2013, 12:21
Nyashka писал(а):
Не вижу в onCreate() создания экземпляра Timer = new Timer(); он там есть?
ээ.. нет))) а для чего он нужен?)
-
Nyashka
- Сообщения: 40
- Зарегистрирован: 19 мар 2013, 13:06
Сообщение
Nyashka » 20 июл 2013, 12:41
Arssir писал(а):Nyashka писал(а):
Не вижу в onCreate() создания экземпляра Timer = new Timer(); он там есть?
ээ.. нет))) а для чего он нужен?)
Ну не знаю) у Вас нульПоинтерЭксцепшн разве не вылетает?)
А ошибка у вас из за того что вы обращаетесь не к экземпляру класса наследованного от класса View (который у вас называется v) а к классу как таковому (который у вас GView). К классу как таковому вы можете обращаться только через статические методы. Что бы получить координально новую ошибку, напишите не GView.postInvalidate(); а v.postInvalidate();
-
Nyashka
- Сообщения: 40
- Зарегистрирован: 19 мар 2013, 13:06
Сообщение
Nyashka » 20 июл 2013, 12:59
И видимо это я Вас ввел в заблуждение вот этим:
Nyashka писал(а): с указанием имени класса наследованного от вьюва (MyView.postInvalidate(); для class MyView extends View{}).
разумеется это неправильно. postInvalidate() надо вызывать для экземпляра класса а не для класса как такового -_-. В мое оправдание я Вас заранее предупредил что
Nyashka писал(а): (или еще сильнее запутать)
-
Arssir
- Сообщения: 38
- Зарегистрирован: 09 июн 2013, 15:22
- Откуда: Москва
Сообщение
Arssir » 20 июл 2013, 13:43
Nyashka писал(а):
Ну не знаю) у Вас нульПоинтерЭксцепшн разве не вылетает?)
А ошибка у вас из за того что вы обращаетесь не к экземпляру класса наследованного от класса View (который у вас называется v) а к классу как таковому (который у вас GView). К классу как таковому вы можете обращаться только через статические методы. Что бы получить координально новую ошибку, напишите не GView.postInvalidate(); а v.postInvalidate();
Сделал как вы сказали. Но если экземпляр класса объявлен в onCreate, то тогда откуда метод schedule() будет знать что такое "v"? Собственно он у меня его и подчеркивает. Сделал по другому, вернул метод schedule() в GView и дописал к его вызову экземпляр v.schedule(), к postInvalidate() ничего приписывать не стал. Больше ошибок не выдает. Спасибо.
Правда приложение при запуске крашится, но это видимо проблема самого кода метода schedule(), который я не особо изучая просто скопировал у вас, попробую разобраться и понять как с ним работать.
-
Arssir
- Сообщения: 38
- Зарегистрирован: 09 июн 2013, 15:22
- Откуда: Москва
Сообщение
Arssir » 20 июл 2013, 15:55
Какая-то проблема с timer.schedule(tTask, 0, 100); с ним крашится, если убрать то запускается, с другими параметрами тоже не работает.
-
Nyashka
- Сообщения: 40
- Зарегистрирован: 19 мар 2013, 13:06
Сообщение
Nyashka » 20 июл 2013, 18:30
Arssir писал(а):
Сделал как вы сказали. Но если экземпляр класса объявлен в onCreate, то тогда откуда метод schedule() будет знать что такое "v"? Собственно он у меня его и подчеркивает. Сделал по другому, вернул метод schedule() в GView и дописал к его вызову экземпляр v.schedule(), к postInvalidate() ничего приписывать не стал. Больше ошибок не выдает. Спасибо.
Что бы знать что такое v, надо объявить его на уровне класса Активити. Конструкцию GView v; вынесите за пределы onCreate, а в самой onCreate() оставьте v= new GView(this);
В GView тоже есть способ поместить таймер, так что бы перерисовка вызывалась самим классом View. Возможно так даже было бы лучше. Но и с таймером в активити тоже должно работать. Я бы вам советовал написать простенькую программу с таймером, а потом переносить полученные конструкции на ваше приложение. Будет проще понять что откуда берется