[英]Use AsyncTask to Load Bitmap Images
I am trying to load an image in the background as someone works through my app. 当有人通过我的应用程序工作时,我正在尝试在后台加载图像。 The logic I wrote is this: 我写的逻辑是这样的:
public class ImageLoader extends AsyncTask <Context, Void, Bitmap>{
private String URL;
private int type;
ImageLoader(String Url, int Type)
{
URL = Url;
type = Type;
}
@Override
protected Bitmap doInBackground(Context... arg0) {
AssetManager assetMgr = arg0[0].getAssets();
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(assetMgr.open(URL));
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onPostExecute( Bitmap result ) {
super.onPostExecute(result);
if (type == 1)
Inst1 = result;
else if (type == 2)
Inst2 = result;
else if (type == 3)
Inst3 = result;
}
}
However when I try to start a new thread like this: 但是,当我尝试启动这样的新线程时:
task = new ImageLoader("Instructions_2.png", 3);
task.execute(gameContext);
But within the program I get the error Looper.prepare must be called, followed by the logic looper.quit() 但是在程序中我得到错误Looper.prepare必须被调用,随后是逻辑looper.quit()
However I seem to break the program when I add Looper.prepare(), and there is no looper.quit() to call. 但是,当我添加Looper.prepare()时,似乎中断了程序,并且没有要调用的looper.quit()。
Am I creating the task correctly? 我是否正确创建任务?
EDIT: 编辑:
This is the error log from when I try to run: 这是我尝试运行时的错误日志:
task = new ImageLoader(gameContext, "Instructions_3.png", 3);
I have a switch case statement that I put the image loader declaration outside of. 我有一个switch case语句,将图像加载器声明放在外面。 Essentially my code is: 本质上,我的代码是:
ImageLoader task;
switch(foo)
{
case 0:
...
task = new ImageLoader(gameContext, "Instructions_0.png", 3);
task.execute();
break;
case 1:
...
task = new ImageLoader(gameContext, "Instructions_1.png", 3));
task.execute();
break;
...
}
And the error log (error occurs every time I hit the task = new ImageLoader(...);
line 和错误日志(每次我执行task = new ImageLoader(...);
时都会发生错误task = new ImageLoader(...);
行
07-20 14:23:34.276: E/AndroidRuntime(16741): FATAL EXCEPTION: Thread-10
07-20 14:23:34.276: E/AndroidRuntime(16741): java.lang.ExceptionInInitializerError
07-20 14:23:34.276: E/AndroidRuntime(16741): at com.petronicarts.stormthecastle.MainGamePanel.update(MainGamePanel.java:2578)
07-20 14:23:34.276: E/AndroidRuntime(16741): at com.petronicarts.stormthecastle.MainThread.run(MainThread.java:63)
07-20 14:23:34.276: E/AndroidRuntime(16741): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
07-20 14:23:34.276: E/AndroidRuntime(16741): at android.os.Handler.<init>(Handler.java:121)
07-20 14:23:34.276: E/AndroidRuntime(16741): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
07-20 14:23:34.276: E/AndroidRuntime(16741): at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
07-20 14:23:34.276: E/AndroidRuntime(16741): at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
07-20 14:23:34.276: E/AndroidRuntime(16741): ... 2 more
The problem is that you are trying to access and operate on UI elements from a non UI thread. 问题是您试图从非UI线程访问UI元素并对其进行操作。 If you change your AsyncTask
as follows, i believe you will be ok: 如果您按照以下方式更改AsyncTask
,我相信您会没事的:
public class ImageLoader extends AsyncTask <Void, Void, Bitmap>{
private String URL;
private int type;
private Context context;
private InputStream in;
ImageLoader(Context context, String Url, int Type)
{
URL = Url;
type = Type;
ImageLoader.this.context = context;
}
@Override
protected void onPreExecute()
{
AssetManager assetMgr = context.getAssets();
try {
in = assetMgr.open(URL);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected Bitmap doInBackground(Void... arg0) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(in);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onPostExecute( Bitmap result ) {
if (type == 1)
Inst1 = result;
else if (type == 2)
Inst2 = result;
else if (type == 3)
Inst3 = result;
}
}
Also change the call of your AyncTask
to something like this: 还要将您的AyncTask
的调用更改为如下所示:
task = new ImageLoader(gameContext, "Instructions_2.png", 3);
task.execute();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.