Java 使用AsyncTask加载位图图像
当有人通过我的应用程序工作时,我正在尝试在后台加载图像。我写的逻辑是:Java 使用AsyncTask加载位图图像,java,android,android-asynctask,loader,Java,Android,Android Asynctask,Loader,当有人通过我的应用程序工作时,我正在尝试在后台加载图像。我写的逻辑是: public class ImageLoader extends AsyncTask <Context, Void, Bitmap>{ private String URL; private int type; ImageLoader(String Url, int Type) { URL = Url; type = Type; }
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;
}
}
但是在程序中,我得到了必须调用的错误Looper.prepare,后跟逻辑Looper.quit()
然而,当我添加Looper.prepare()时,我似乎破坏了程序,并且没有Looper.quit()可调用
我是否正确创建了任务
编辑:
这是我尝试运行时的错误日志:
task = new ImageLoader(gameContext, "Instructions_3.png", 3);
我有一个switch-case语句,我将图像加载器声明放在它的外部。基本上,我的代码是:
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;
...
}
以及错误日志(每次我点击task=newimageloader(…);
行时都会发生错误)
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
07-20 14:23:34.276:E/AndroidRuntime(16741):致命异常:线程10
07-20 14:23:34.276:E/AndroidRuntime(16741):java.lang.ExceptionInInitializeError
07-20 14:23:34.276:E/AndroidRuntime(16741):在com.petronicarts.stormthecastle.MainGamePanel.update(MainGamePanel.java:2578)
07-20 14:23:34.276:E/AndroidRuntime(16741):在com.petronicarts.stormthecastle.MainThread.run(MainThread.java:63)
07-20 14:23:34.276:E/AndroidRuntime(16741):原因:java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序
07-20 14:23:34.276:E/AndroidRuntime(16741):在android.os.Handler.(Handler.java:121)
07-20 14:23:34.276:E/AndroidRuntime(16741):在android.os.AsyncTask$InternalHandler。(AsyncTask.java:421)
07-20 14:23:34.276:E/AndroidRuntime(16741):在android.os.AsyncTask$InternalHandler。(AsyncTask.java:421)
07-20 14:23:34.276:E/AndroidRuntime(16741):在android.os.AsyncTask.(AsyncTask.java:152)
07-20 14:23:34.276:E/AndroidRuntime(16741):…还有两个
问题在于您试图从非UI线程访问和操作UI元素。如果您按以下方式更改异步任务,我相信您会没事的:
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;
}
}
我仍然收到一个关于不调用Looper.prepare()的错误。理想的放置位置是哪里?@NathanTornquist您能发布错误日志并指出代码中引发异常的行吗?@Nathantorquist您是否从另一个线程调用switch case语句,该线程不是UI线程?如果是这样,请尝试调用ImageLoader AsyncTask
如下所示:runOnUiThread(new Runnable(){public void run(){task=new ImageLoader(游戏上下文,“指令0.png”,3);task.execute();})
在开关
块中的案例
语句中。我有一个活动将onPause、onResume、onDestroy等事件发送到我的MainGamePanel。该MainGamePanel是一个扩展的SurfaceView。我有一个主线程,在我的MainGamePanel中运行更新和绘制功能。当MainGameePanel已初始化。--我希望一切都有意义。这样,我似乎没有访问runOnUiThread的权限。@Nathantorquist如果您这样称呼它,您可以在runOnUiThread
方法中访问:yourActivity.runOnUiThread(…)
,其中yourActivity
是对屏幕上显示的活动的引用。我不知道我的建议是否能肯定地解决您的问题,但发生在您身上的错误只有在您从UI线程处理UI元素时才会发生,因此这是您需要查找的。希望这能有所帮助。
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;
}
}
task = new ImageLoader(gameContext, "Instructions_2.png", 3);
task.execute();