在我的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;
}
}
答案 0 :(得分:1)
您正在从工作线程调用AsyncTask。这样它就无法访问UI线程。您可能应该考虑使用Handler。
答案 1 :(得分:0)
问题可能是你必须在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线程上运行。
答案 2 :(得分:0)
我通过使用Handler Thread解决了这个问题。