Тема не может получить доступ к представлению - Android - PullRequest
0 голосов
/ 29 ноября 2011

Я пишу приложение для фонарика, которое является «подсветкой экрана» для любого телефона без фонарика. Я хочу иметь настройку, которая включает функцию Strobe Light. Тем не менее, с этим типом «фонарика» я подумал, что самый простой способ сделать это, это изменить фон вида. Я делаю это в отдельном потоке, потому что я использую SeekBar, чтобы узнать, как быстро должен мигать стробелайт. Тем не менее, я получаю сообщение об ошибке, что поток не может получить доступ к представлению, потому что это не поток, который создал его. Есть предложения?

Вот что содержится в onCreate ():

        mSeekBar = (SeekBar) findViewById(R.id.seekBar);
        mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){
          public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {

                final Thread strober = new Thread(new Runnable(){
                    public void run(){
                        strobeLight();
                    }
                });             
                if (mSeekBar.getProgress()>0) {
                    runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        strober.start();
                    }
                    });
                }
                else {
                    runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        strober.interrupt();
                        relLayout.setBackgroundColor(color.all_white);
                    }
                    });
                }
          }
          public void onStartTrackingTouch(SeekBar seekBar) {}
          public void onStopTrackingTouch(SeekBar seekBar) {}          
        }); 

Вот метод strobeLight ():

public void strobeLight(){
    boolean lightIsOn=true;

    runOnUiThread(new Runnable() {
    @Override
    public void run() { 
            do {
                    if (lightIsOn){
                        relLayout.setBackgroundColor(color.all_black);
                        try { Thread.sleep(1000/(mSeekBar.getProgress()+2)); }
                            catch (InterruptedException e) {}
                        lightIsOn=false; 
                        strobeActivated=true;}
                    else{
                        relLayout.setBackgroundColor(color.all_white);  
                        try { Thread.sleep(1000/(mSeekBar.getProgress()+2)); }
                            catch (InterruptedException e) {}                       
                        lightIsOn=true; }
                    if (mSeekBar.getProgress()<1)
                        strobeActivated=false;
            } while (strobeActivated);
            relLayout.setBackgroundColor(color.all_white);
    }
});   
}   

Вот LogCat для кода выше:

11-28 17:17:58.383: E/ActivityManager(16877): ANR in com.marshall.meadows182 (com.marshall.meadows182/.LightNoTorch),  time=603431510
11-28 17:17:58.383: E/ActivityManager(16877): Reason: keyDispatchingTimedOut
11-28 17:17:58.383: E/ActivityManager(16877): Load: 1.53 / 1.62 / 1.62
11-28 17:17:58.383: E/ActivityManager(16877): CPU usage from 14662ms to 0ms ago:
11-28 17:17:58.383: E/ActivityManager(16877):   0.8% 16877/system_server: 0.4% user + 0.4% kernel / faults: 7 minor
11-28 17:17:58.383: E/ActivityManager(16877):   0% 14673/com.qikffc.android: 0% user + 0% kernel / faults: 151 minor
11-28 17:17:58.383: E/ActivityManager(16877):   0.2% 16957/com.android.systemui: 0.2% user + 0% kernel / faults: 1 minor
11-28 17:17:58.383: E/ActivityManager(16877):   0.1% 16999/com.android.phone: 0% user + 0% kernel
11-28 17:17:58.383: E/ActivityManager(16877):   0.1% 13/kondemand/0: 0% user + 0.1% kernel
11-28 17:17:58.383: E/ActivityManager(16877):   0% 68/rild: 0% user + 0% kernel / faults: 6 minor
11-28 17:17:58.383: E/ActivityManager(16877):   0% 14830/logcat: 0% user + 0% kernel
11-28 17:17:58.383: E/ActivityManager(16877):   0.1% 14868/com.marshall.meadows182: 0% user + 0% kernel / faults: 9 minor
11-28 17:17:58.383: E/ActivityManager(16877):   0% 24825/adbd: 0% user + 0% kernel
11-28 17:17:58.383: E/ActivityManager(16877):   0% 5446/com.google.android.apps.maps:NetworkLocationService: 0% user + 0% kernel
11-28 17:17:58.383: E/ActivityManager(16877):   0% 7839/wpa_supplicant: 0% user + 0% kernel / faults: 3 minor
11-28 17:17:58.383: E/ActivityManager(16877):   0% 17054/com.google.process.gapps: 0% user + 0% kernel / faults: 4 minor
11-28 17:17:58.383: E/ActivityManager(16877):   0% 25055/iqd: 0% user + 0% kernel
11-28 17:17:58.383: E/ActivityManager(16877): 2.7% TOTAL: 1.8% user + 0.8% kernel
11-28 17:17:58.383: E/ActivityManager(16877): CPU usage from 416ms to 935ms later with 99% awake:
11-28 17:17:58.383: E/ActivityManager(16877):   7.4% 16877/system_server: 0% user + 7.4% kernel / faults: 6 minor
11-28 17:17:58.383: E/ActivityManager(16877):     9.2% 16923/InputDispatcher: 1.8% user + 7.4% kernel
11-28 17:17:58.383: E/ActivityManager(16877): 3.8% TOTAL: 0% user + 3.8% kernel

Ответы [ 2 ]

2 голосов
/ 29 ноября 2011

Сообщение об ошибке не требует пояснений. Вы не можете вызывать многие методы представлений вне потока, в котором они были созданы, известного как поток пользовательского интерфейса.

Проблема в линиях

relLayout.setBackgroundColor(...);

которые запускаются в вашей теме. Вы должны запустить их в потоке пользовательского интерфейса следующим образом:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        relLayout.setBackgroundColor(...);
    }
});
0 голосов
/ 29 ноября 2011

Это нормально, вы не можете изменить пользовательский интерфейс там. Я бы предложил использовать AsyncTask и изменить пользовательский интерфейс на методе onPostExecute. В любом случае, если вы не хотите изменять, вы должны изменить пользовательский интерфейс, используя обработчики.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...