Форум программистов, компьютерный форум, киберфорум
Программирование Android
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/18: Рейтинг темы: голосов - 18, средняя оценка - 4.56
27 / 41 / 13
Регистрация: 15.05.2013
Сообщений: 1,313

На эмуляторе работает, а в смартфоне нет

07.05.2014, 15:03. Показов 4009. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Подскажите, в чём ошибка?
В android sdk работает, а в смарте нет.
А должен просто появится один символ на экране, и переместиться слева на право.
Смартфон почему-то зависает, начинает тормозить
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.widget.TextView;
import android.graphics.*;
 
public class MainSurface extends Activity{
    
    MySurface mysurface;
    
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        mysurface = new MySurface(this);
        setContentView(mysurface);
    }
    
    public void onResume(){
        super.onResume();
        mysurface.onResume();
    }
    
    public class MySurface extends SurfaceView{
        
        SurfaceHolder holder;
        Thread thread;
        TextView txt;
        Paint pt;
        boolean running;
        int x,y;
        
        MySurface(Context context){
            super(context);
            holder = getHolder();
            txt = new TextView(context);
            pt = new Paint();
            x = 10; y = 100;
        }
        
        public void onResume(){
            thread = new Thread(mrun);
            thread.start();
            running = true;
        }
        
        Runnable mrun = new Runnable() {
            public void run() {
                pt.setColor(Color.GREEN);
                while (running) {
                    Canvas canv = null;
                    canv = holder.lockCanvas();
                    if (canv == null)
                        continue;
                    canv.drawRGB(0, 0, 0);
                    canv.drawText("O", x, y, pt);
                    x += 10;
                    try {
                        Thread.sleep(100);
                    } catch (Exception e) {}
 
                    holder.unlockCanvasAndPost(canv);
                }
            }
        };
    }
    
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.05.2014, 15:03
Ответы с готовыми решениями:

Сравнение координат: на эмуляторе - работает, на устройстве - нет
Добрый день. запускаю на эмуляторе - он считывает мои координаты. посылаю через эмулятор новые координаты - он их считывает, сравнивает с...

Нет приложения в эмуляторе
Привет. Такая проблема: создал пустое приложение Android, но когда начинаю отладку, то запускается не приложение а просто эмулятор. В...

Xamarin, приложение устанавливается на телефон, но не работает, хотя работает на эмуляторе
Приложения не запускаются на телефоне, хотя в эмуляторе работают нормально. а манифесте по версиям сходится все, на телефоне 4.0.3, так же...

5
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
07.05.2014, 15:55
Поток создаётся в OnResume и нигде не убивается.
Грубо говоря, получив десяток OnResume, Activity создает десяток потоков, которые одновременно пытаются что-то делать.

Обычно запуск потока ставят в surfaceCreated, а убийство - в surfaceDestroyed.
0
27 / 41 / 13
Регистрация: 15.05.2013
Сообщений: 1,313
07.05.2014, 20:58  [ТС]
Цитата Сообщение от Patch Посмотреть сообщение
Грубо говоря, получив десяток OnResume, Activity создает десяток потоков
это если несколько раз запустить приложение, и несколько раз с ним что-то делать: например сворачивать и разворачивать, тогда OnResume запустится несколько раз!
А тут прога сразу глючит, при первом запуске и перемещение символа не отображается
0
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
07.05.2014, 21:23
Да я что-то не вижу, чтобы ты его на весь экран развернул.
А это значит, что служебная часть экрана - та, где, антивирусы и подключение к вай-фаю отображаются, еще как могут захватывать экран.
Упс!
Вот так вот.
Загрузил в телефон приложение, антивирус его поставил на паузу, проверил и сообщил об этом... и возобновил. И пошло у тебя ДВА потока, конкурирующих за экран.

Делай по-человечески.
1
27 / 41 / 13
Регистрация: 15.05.2013
Сообщений: 1,313
07.05.2014, 23:18  [ТС]
Цитата Сообщение от Patch Посмотреть сообщение
Делай по-человечески
научусь, конечно буду делать! Тем более если так настаиваеш.
А пока у меня опыта нет.

Кстати я добавил метод onResume и onDestroy, теперь приложение то работает, то нет.
Т.е. если несколько раз позапускать прогу, то бывает показывает перемещающийся символ, а бывает глючит, и даже кнопка назад не работает!
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
public class MainActivity extends Activity{
    
    MySurface mysurface;
    
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                             WindowManager.LayoutParams.FLAG_FULLSCREEN);
        
        mysurface = new MySurface(this);
        setContentView(mysurface);
    }
    
    public void onResume(){
        super.onResume();
        mysurface.resume();
    }
 
    @Override
    protected void onPause()
    {
        // TODO: Implement this method
        super.onPause();
        mysurface.pause();
        
    }
 
    @Override
    protected void onDestroy()
    {
        // TODO: Implement this method
        super.onDestroy();
        mysurface.destroy();
    }
    
    
 
 
    public class MySurface extends SurfaceView
{
          //  implements Runnable{
        
        SurfaceHolder holder;
        Thread thread;
        TextView txt;
        Paint pt;
        boolean running;
        int x,y;
        
        MySurface(Context context){
            super(context);
            holder = getHolder();
            txt = new TextView(context);
            pt = new Paint();
            x = 10; y = 100;
        }
        
        public void resume(){
            thread = new Thread(mrun);
            thread.start();
            running = true;
        }
        
        public void pause(){
            running = false;
        }
        
        public void destroy(){
            running = false;
            thread.interrupt();
        }
        
        Runnable mrun = new Runnable() {
            public void run() {
                pt.setColor(Color.GREEN);
                while (running) {
                    if(!holder.getSurface().isValid())
                        continue;         
                    Canvas canv = null;
                    canv = holder.lockCanvas();
                    if (canv == null)
                        continue;
                    canv.drawRGB(0, 0, 0);
                    canv.drawText("O", x, y, pt);
                    x += 10;
                    try {
                        Thread.sleep(100);
                    } catch (Exception e) {}
 
                    //if(canv != null)
                        holder.unlockCanvasAndPost(canv);
                }
            }
        };
    }
    
}
0
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
08.05.2014, 08:33
Цитата Сообщение от phpk Посмотреть сообщение
Кстати я добавил метод onResume и onDestroy, теперь приложение то работает, то нет.
Молодец.

И вот прикинь, как оно теперь работает:
Стартует Activity.
Срабатывает Activity.onCreate(): создается SurfaceView()
Срабатывает SurfaceView.surfaceCreated()
Срабатывает Activity.OnStart()
Срабатывает Activity.OnResume() - вызывает SurfaceView.resume(): создаётся второй поток
Запускается процедура run() второго потока, и в половине случаев тут-же выходит, поскольку переменная running на этот момент еще НЕ ИНИЦИАЛИЗИРОВАНА и находиться в хрен-знает-каком состоянии - и цикл обработки может вообще не запуститься
Затем в SurfaceView.resume() срабатывает running = true; но уже поздно - второй поток, скорее всего, уже закрылся.

Если тебе повезло, и поток вошел в цикл - срабатывает любой случайный чих на экран.
От активности сервисов, до случайного взмаха рукой, да мало ли от чего...
У меня вот смартфон беситься начинает, если рядом с ним на зарядке старый телефон лежит.
Ток в проводе зарядки воспринимается иногда как нажатия и жесты.

При этом
Срабатывает Activity.OnPause() - вызывает SurfaceView.pause()
А там - running = false;
Но поток-то никуда не делся.
Снова срабатывает Activity.OnResume() - вызывает SurfaceView.resume()
Создаётся третий поток, в котором тоже running в хрен-знает-каком состоянии.

И вот ты пытаешься всю эту фигню закрыть и тут...
Срабатывает Activity.OnDestroy() - вызывает SurfaceView.destroy()
А в нем:
Java
1
2
 running = false;
            thread.interrupt();
Прям вот так и написано.

Прикинь просто:
вот сделал ты running = false;
А в этот момент твой второй поток что-то там рисовал на экране
отрабатывал canv.drawRGB(0, 0, 0), например.
Не может он мгновенно завершиться и до проверки условия while (running) дойти - ему дорисовать надо, да еще и твое Thread.sleep(100) в конце отработать.
А тут ты ему такой бац!! thread.interrupt()
И экран твоего девайса зависает нафиг, просто потому, что канва захвачена потоком, который что-то там рисовал, а ты это поток уже убил к чертовой матери.
И как рисовать что-то твой андроид уже не знает - получить канву экрана он не может, и освободить ее некому.

Вот такую вот фигню ты написал.

А по-человечески это будет примерно так:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
public class MySurface extends SurfaceView {
 
    private SurfaceHolder holder;
    private Thread gameLoopThread;
    private TextView txt;
    private Paint pt;
    boolean running;
    int x,y;
    
    Runnable mrun = new Runnable() {
      public void run() {
    long ticksPS = 1000 / 20; //установка отрисовки на 20 кадров в секунду
    long startTime;
    long sleepTime;
   
    while (running) {
           Canvas c = null;
           startTime = System.currentTimeMillis();
                        try { 
                          c = getHolder().lockCanvas();
                          synchronized (getHolder()) {
                              c.drawRGB(0, 0, 0);
                                c.drawText("O", x, y, pt);
                                x += 10;
                  }
           } finally {
                  if (c != null) {
                         getHolder().unlockCanvasAndPost(c);
                  }
           }
           sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
           try {
                  if (sleepTime > 0)
                    Thread.sleep(sleepTime);
                  else
                    Thread.sleep(10);
           } catch (Exception e) {}
        }
      }
      
  };
 
 
    public MySurface(Context context) {
        
            super(context);
            txt = new TextView(context);
            pt = new Paint();
            x = 10; y = 100;
          gameLoopThread = new Thread(mrun);
          holder = getHolder();
          holder.addCallback(new SurfaceHolder.Callback() {
 
                 @Override
                 public void surfaceDestroyed(SurfaceHolder holder) {
                        boolean retry = true;
                        running = false;
                        while (retry) {
                               try {
                                     gameLoopThread.join();
                                     retry = false;
                               } catch (InterruptedException e) {
                               }
                        }
                 }
 
                 @Override
                 public void surfaceCreated(SurfaceHolder holder) {
                        running = true;
                        gameLoopThread.start();
 
                 }
 
                 @Override
                 public void surfaceChanged(SurfaceHolder holder, int format,
                               int width, int height) {
                 }
          });
         
         
}
}
Правильность всех запятых и прочего не проверял - главное, чтобы ты понял идею верного построения приложения.
По-хорошему, поток надо вообще в отдельный класс вынести.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.05.2014, 08:33
Помогаю со студенческими работами здесь

Netbeans: приложения нет в эмуляторе
Вот такая проблема: Работаю в Netbeans. Эмулятор запускается нормально, но созданного приложения в нем нет. Спасибо заранее за...

Нет ярлыка приложения в эмуляторе
Здравствуйте. Абсолютный новичок в android разработке, но не новичок в разработке вообще. Установил eclips, открыл тестовый hello world,...

RSS-читалка - работает на эмуляторе, не работает на реальном девайсе
День добрый. Есть несложная читалка на основе вот этой вот, для парсинга используется Android SAX. Все прекрасно работает на эмуляторе, но...

eclipsе (в эмуляторе нет моей программы)
Здравствуйте! Поставил эклипс по след схеме: 1)скачать классик с офф сайта 2)через прогу поставил адт плагин 3)скачвал сдк ...

Почему нет кнопок навигации в эмуляторе?
Android Studio, только что установил, новый стандартный проект, первый запуск. При компиляции никаких ошибок нет Где чего проверить?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит: токи, напряжения и их 1 и 2 производные при t = 0;. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru