如何在android中定期更改背景图像
在我的android应用程序中,我需要在10秒钟内更改图像视图中的背景图像一次。因此,我在run方法中调用异步任务。当我执行应用程序时,它崩溃了。 它向我提供由以下原因引起的如何在android中定期更改背景图像,android,android-imageview,android-image,android-asynctask,Android,Android Imageview,Android Image,Android Asynctask,在我的android应用程序中,我需要在10秒钟内更改图像视图中的背景图像一次。因此,我在run方法中调用异步任务。当我执行应用程序时,它崩溃了。 它向我提供由以下原因引起的:java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序异常 我知道我必须使用线程,但我不知道如何正确地这样做。请帮帮我 这是我的代码示例: public void onCreate(Bundle savedInstanceState) { su
:java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序异常
我知道我必须使用线程,但我不知道如何正确地这样做。请帮帮我
这是我的代码示例:
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;
}
}
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
.................
新线程()
{
公开募捐
{
while(true){
尝试
{
睡眠(5000);
}
捕捉(中断异常e)
{
e、 printStackTrace();
}
计数=计数+1;
新建ImageChange().execute();
}
}
}.start();
}//OnCreate结束
类ImageChange扩展了异步任务
{
受保护的void onPreExecute(){
}
受保护的void onPostExecute(未使用的void){
iv1.设置图像位图(b1);
iv2.设置图像位图(b2);
}
受保护的Void doInBackground(Void…arg0){
开关(计数){
案例1:
b1=位图工厂.decodeFile(f1.getAbsolutePath());
b2=位图工厂.decodeFile(f2.getAbsolutePath());
打破
案例2:
b1=位图工厂.decodeFile(f2.getAbsolutePath());
b2=位图工厂.decodeFile(f1.getAbsolutePath());
打破
违约:
计数=0;
b1=位图工厂.decodeFile(f1.getAbsolutePath());
b2=位图工厂.decodeFile(f2.getAbsolutePath());
打破
}
返回null;
}
}
您正在从工作线程调用AsyncTask。这样它就无法访问UI线程。你可能应该考虑使用一个处理程序。 可能,问题是你必须在UI线程中执行<代码> IIGEXECTION.DOIBACKEATE()方法。尝试按以下方式更改代码:
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);
}
});
}
}
也考虑使用类
的可能性。
编辑:使用以下命令更改代码的活动部分:
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线程上运行。我通过使用处理程序线程解决了这个问题。好的,在我研究您的问题之前,有几件事让我感到震惊:(1)在将b1和b2设置为其他对象之前,无需将它们设置为null,这没有特殊效果。(2) 在Java中命名类的好方法是使用CamelCase:将其命名为ImageChange而不是ImageChange请参阅我的回答的编辑部分谢谢,但是在doInBackground完成时将调用PostExecute方法。因为你的逻辑背景永远无法完成。请帮帮我。
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;
}