【问题标题】:how to change background image periodically in android如何在android中定期更改背景图像
【发布时间】:2011-11-18 13:18:59
【问题描述】:

在我的 android 应用程序中,我需要在 10 秒内更改图像视图中的背景图像。以便我在运行方法中调用异步任务。当我执行应用程序时它崩溃了。 它给了我Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() Exception。

我知道我必须使用 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;
    }
}   

【问题讨论】:

  • 好的,在我调查你的问题之前,有几件事让我印象深刻:(1)在将它们设置为其他值之前无需将 b1 和 b2 设置为 null,这没有特殊效果。 (2) 在Java中命名一个类的好方法是使用CamelCase:将其命名为ImageChange而不是imagechange

标签: android android-imageview android-image android-asynctask


【解决方案1】:

您正在从工作线程调用 AsyncTask。这样它就无法访问 UI 线程。您可能应该考虑使用处理程序。

【讨论】:

    【解决方案2】:

    可能问题在于你必须在 UI 线程中执行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类的可能性

    编辑:更改代码的活动部分:

    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 循环中插入的代码必须在 UI 线程中运行;实际上,AsyncTask 类的每个 onPostExecute 方法都运行在 UI 线程上。

    【讨论】:

    • 查看我回答的编辑部分
    • 谢谢,但是当 doInBackground 完成时会调用 PostExecute 方法。因为你的逻辑 doInBackground 永远不会完成。请帮帮我。
    【解决方案3】:

    我通过使用 Handler Thread 解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-27
      相关资源
      最近更新 更多