Используйте AsyncTask для загрузки растровых изображений
Я пытаюсь загрузить изображение в фоновом режиме, как кто-то работает через мое приложение. Логика, которую я написал, такова:
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;
}
}
Однако, когда я пытаюсь начать новую тему, как это:
task = new ImageLoader("Instructions_2.png", 3);
task.execute(gameContext);
Но внутри программы я получаю сообщение об ошибке Looper.prepare, после чего следует логика looper.quit()
Однако, кажется, что я нарушаю программу, когда добавляю Looper.prepare(), и нет looper.quit() для вызова.
Я правильно создаю задачу?
РЕДАКТИРОВАТЬ:
Это журнал ошибок, когда я пытаюсь запустить:
task = new ImageLoader(gameContext, "Instructions_3.png", 3);
У меня есть инструкция переключения регистра, в которую я помещаю объявление загрузчика изображений. По сути мой код:
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 = 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
1 ответ
Проблема в том, что вы пытаетесь получить доступ к элементам пользовательского интерфейса и работать с ними не из потока пользовательского интерфейса. Если вы измените свой 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;
}
}
Также измените вызов вашего AyncTask
что-то вроде этого:
task = new ImageLoader(gameContext, "Instructions_2.png", 3);
task.execute();