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

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

07.05.2014, 15:03. Показов 4105. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru