как периодически менять фоновое изображение в андроиде - PullRequest
2 голосов
/ 18 ноября 2011

в моем приложении на Android, мне нужно изменить фоновое изображение в представлении изображения на 10 секунд один раз. так что я вызываю асинхронную задачу в методе запуска. когда я запускаю приложение, оно падает. Это дает мне Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() исключение.

Я знаю, что должен использовать Thread, но не знаю, как это сделать правильно. Пожалуйста, помогите мне.

Это мой пример кода:

    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
        .................
    new Thread() 
    {
        public void run() 
        {
            while(true){
            try 
            {
                Thread.sleep(5000);
            } 
            catch (InterruptedException e) 
            {
                e.printStackTrace();
            }
            count = count + 1;

            new ImageChange().execute();
          }
        }       
    }.start();  

} // OnCreate End


class ImageChange extends AsyncTask<Void, Void, Void> 
{       
    protected void onPreExecute() { 

    }   
    protected void onPostExecute(Void unused) {
        iv1.setImageBitmap(b1);
        iv2.setImageBitmap(b2);
    }
    protected Void doInBackground(Void... arg0) {

        switch(count){

            case 1:            


                b1 = BitmapFactory.decodeFile(f1.getAbsolutePath());
                b2 = BitmapFactory.decodeFile(f2.getAbsolutePath());    
            break;  
            case 2:


                b1 = BitmapFactory.decodeFile(f2.getAbsolutePath());
                b2 = BitmapFactory.decodeFile(f1.getAbsolutePath());

            break;      
            default :
                count = 0;      
                b1 = BitmapFactory.decodeFile(f1.getAbsolutePath());
                b2 = BitmapFactory.decodeFile(f2.getAbsolutePath());

            break;    
        }

     return null;
    }
}   

Ответы [ 3 ]

1 голос
/ 18 ноября 2011

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

0 голосов
/ 25 ноября 2011

Я решил проблему с помощью потока обработчика.

0 голосов
/ 18 ноября 2011

Возможно, проблема в том, что вы должны выполнить метод ImageChange.doInBackground() в потоке пользовательского интерфейса.Попробуйте изменить свой код следующим образом:

class ImageChange extends AsyncTask<Void, Void, Void> {

    Activity act;

    public ImageChange(Activity act) {
        this.act = act;
    }

    protected void onPostExecute(Void unused) {
        iv1.setImageBitmap(b1);
        iv2.setImageBitmap(b2);
    }
    protected Void doInBackground(Void... arg0) {

        switch(count) {
            case 1:            
                helperMethod(f1.getAbsolutePath(), f2.getAbsolutePath());
            break;  
            case 2:
                helperMethod(f2.getAbsolutePath(), f1.getAbsolutePath());
            break;      
            default :
                count = 0;      
                helperMethod(f1.getAbsolutePath(), f2.getAbsolutePath());
            break;    
        }

        return null;
    }

    private void helperMethod(String a, String b) {
        act.runOnUIThread(new Runable() {
            public void run() {
                b1 = BitmapFactory.decodeFile(a);
                b2 = BitmapFactory.decodeFile(b);
            }
        });
    }
}

Обратите внимание, что вы должны передать Activity в конструктор класса ImageChange.Это означает, что вы должны вызывать asyncTask следующим образом:

new ImageChange(this).execute();

Также рассмотрите возможность использования класса TimerTask

EDIT: изменить часть действияВаш код с этим:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
        .................

    new ImageChange().execute();

} // OnCreate End

И добавьте while(true) к классу ImageChange:

    protected Void doInBackground(Void... arg0) {
        while(true) {

            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            count = count + 1;

            switch(count) {
                ...    
            }
        }
        return null;
    }

EDIT2: Вы можете решить проблему вставки кода, который должен быть выполнен в onPostExecuteпосле каждой итерации внутри цикла while:

    protected Void doInBackground(Void... arg0) {
        while(true) {

            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            count = count + 1;

            switch(count) {
                ...    
            }
            act.runOnUIThread(new Runnable() {
                public void run() {
                    iv1.setImageBitmap(b1);
                    iv2.setImageBitmap(b2);
                }
            });
        }
        return null;
    }

Код, который вы вставляете в цикл while, должен выполняться в потоке пользовательского интерфейса;фактически каждый метод onPostExecute класса AsyncTask выполняется в потоке пользовательского интерфейса.

...