如何在 AsyncTask 中加载 imageView
How to load imageViews in AsyncTask
我的应用程序中有 ViewPager,其中包含 7 个片段,每个片段包含多个图像。
我想在每个片段加载它的图像时显示 ProgressBar。
所以我创建了 AsyncTask 在后台加载图像。
问题是我无法使用 Picasso 库加载图像,它显示了一些错误。
谁能帮我想想怎么做?
编辑: 我问这个的原因是因为用 Picasso 加载所有图像需要大约 1.5 秒,而且看起来很慢。 "android:src" 应用程序有时会因为 OutOfMemory 问题而崩溃,"The application may be doing too much work on its main thread." 所以我正在寻找更好的方法。
谢谢!!!
fragment1.java:
public class Fragment1 extends Fragment {
public Fragment1() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_frag1, container, false);
LoadImagesTask loadImagesTask = new LoadImagesTask();
loadImagesTask.execute();
// Inflate the layout for this fragment
return rootView;
}
private class LoadImagesTask extends AsyncTask<Void, Void, Void> {
ProgressBar progressBar = (ProgressBar) getActivity().findViewById(R.id.loading);
ImageView image1 = (ImageView) getActivity().findViewById(R.id.imageView_S0P1);
ImageView image2 = (ImageView) getActivity().findViewById(R.id.imageView_S0P2);
ImageView image3 = (ImageView) getActivity().findViewById(R.id.imageView_S0P3);
ImageView image4 = (ImageView) getActivity().findViewById(R.id.imageView_S0P4);
ImageView image5 = (ImageView) getActivity().findViewById(R.id.imageView_S0P5);
ImageView image6 = (ImageView) getActivity().findViewById(R.id.imageView_S0P6);
ImageView image7 = (ImageView) getActivity().findViewById(R.id.imageView_S0P7);
ImageView image8 = (ImageView) getActivity().findViewById(R.id.imageView_S0P8);
ImageView image9 = (ImageView) getActivity().findViewById(R.id.imageView_S0P9);
ImageView image10 = (ImageView) getActivity().findViewById(R.id.imageView_S0P10);
@Override
protected Void doInBackground(Void... params) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Picasso.with(getActivity()).load(R.drawable.s0p1).into(image1);
Picasso.with(getActivity()).load(R.drawable.s0p2).into(image2);
Picasso.with(getActivity()).load(R.drawable.s0p3).into(image3);
Picasso.with(getActivity()).load(R.drawable.s0p4).into(image4);
Picasso.with(getActivity()).load(R.drawable.s0p5).into(image5);
Picasso.with(getActivity()).load(R.drawable.s0p6).into(image6);
Picasso.with(getActivity()).load(R.drawable.s0p7).into(image7);
Picasso.with(getActivity()).load(R.drawable.s0p8).into(image8);
Picasso.with(getActivity()).load(R.drawable.s0p9).into(image9);
Picasso.with(getActivity()).load(R.drawable.s0p10).into(image10);
}
});
return null;
}
@Override
protected void onPostExecute(Void event) {
progressBar.setVisibility(View.GONE);
}
}
}
Logcat:
07-12 17:03:32.838 17497-17581/appinventor.ai_itiel_maimon.Rubiks_cube E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: appinventor.ai_itiel_maimon.Rubiks_cube, PID: 17497
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.IllegalStateException: Method call should happen from the main thread.
at com.squareup.picasso.Utils.checkMain(Utils.java:136)
at com.squareup.picasso.RequestCreator.into(RequestCreator.java:615)
at com.squareup.picasso.RequestCreator.into(RequestCreator.java:601)
at appinventor.ai_itiel_maimon.Rubiks_cube.Intro$LoadImagesTask.doInBackground(Intro.java:68)
at appinventor.ai_itiel_maimon.Rubiks_cube.Intro$LoadImagesTask.doInBackground(Intro.java:36)
at android.os.AsyncTask.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
AsyncTask 背后的想法是 doInBackground 执行后台工作,然后您可以 return 一些东西将作为参数传递给在主线程中执行的 onPostExecute。
所以尝试从 onPostExecute() 方法设置图像 :)
但是你可以在不使用 AsyncTask 的情况下轻松地做到这一点,就像这样:
public class BlankFragment extends Fragment {
private ImageView imv1;
private ImageView imv2;
private ImageView imv3;
private ImageView imv4;
private ImageView imv5;
private ImageView imv6;
private ImageView imv7;
private ImageView imv8;
private ImageView imv9;
ProgressDialog progressDialog = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
imv1 = (ImageView) getActivity().findViewById(R.id.imageView);
imv2 = (ImageView) getActivity().findViewById(R.id.imageView2);
imv3 = (ImageView) getActivity().findViewById(R.id.imageView3);
imv4 = (ImageView) getActivity().findViewById(R.id.imageView4);
imv5 = (ImageView) getActivity().findViewById(R.id.imageView5);
imv6 = (ImageView) getActivity().findViewById(R.id.imageView6);
imv7 = (ImageView) getActivity().findViewById(R.id.imageView7);
imv8 = (ImageView) getActivity().findViewById(R.id.imageView8);
imv9 = (ImageView) getActivity().findViewById(R.id.imageView9);
}
private void setImage() {
// show progress dialog
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
// set your images here.
}
});
// dismiss progressDialog here
}
}
如果您想得到一个好的答案,您应该 post 在这里添加一些代码。
一般来说,您可以简单地将可绘制对象用作 ImageView xml 实体中的 "android:src"(您在这里所做的几乎相同,只是使用此处的编程方法...)
或者在 Main\UI 线程上使用 Picasso(它与单独负责渲染 UI 组件的线程同名),即在 inflate 方法上。
一般来说,尝试检查更多 'how to' 使用片段和一般 android 设计模式的教程,你显然还在学习,但使用谷歌推荐的方法会更容易您的学习并最大限度地减少错误。
我的应用程序中有 ViewPager,其中包含 7 个片段,每个片段包含多个图像。 我想在每个片段加载它的图像时显示 ProgressBar。 所以我创建了 AsyncTask 在后台加载图像。 问题是我无法使用 Picasso 库加载图像,它显示了一些错误。 谁能帮我想想怎么做?
编辑: 我问这个的原因是因为用 Picasso 加载所有图像需要大约 1.5 秒,而且看起来很慢。 "android:src" 应用程序有时会因为 OutOfMemory 问题而崩溃,"The application may be doing too much work on its main thread." 所以我正在寻找更好的方法。
谢谢!!!
fragment1.java:
public class Fragment1 extends Fragment {
public Fragment1() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_frag1, container, false);
LoadImagesTask loadImagesTask = new LoadImagesTask();
loadImagesTask.execute();
// Inflate the layout for this fragment
return rootView;
}
private class LoadImagesTask extends AsyncTask<Void, Void, Void> {
ProgressBar progressBar = (ProgressBar) getActivity().findViewById(R.id.loading);
ImageView image1 = (ImageView) getActivity().findViewById(R.id.imageView_S0P1);
ImageView image2 = (ImageView) getActivity().findViewById(R.id.imageView_S0P2);
ImageView image3 = (ImageView) getActivity().findViewById(R.id.imageView_S0P3);
ImageView image4 = (ImageView) getActivity().findViewById(R.id.imageView_S0P4);
ImageView image5 = (ImageView) getActivity().findViewById(R.id.imageView_S0P5);
ImageView image6 = (ImageView) getActivity().findViewById(R.id.imageView_S0P6);
ImageView image7 = (ImageView) getActivity().findViewById(R.id.imageView_S0P7);
ImageView image8 = (ImageView) getActivity().findViewById(R.id.imageView_S0P8);
ImageView image9 = (ImageView) getActivity().findViewById(R.id.imageView_S0P9);
ImageView image10 = (ImageView) getActivity().findViewById(R.id.imageView_S0P10);
@Override
protected Void doInBackground(Void... params) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
Picasso.with(getActivity()).load(R.drawable.s0p1).into(image1);
Picasso.with(getActivity()).load(R.drawable.s0p2).into(image2);
Picasso.with(getActivity()).load(R.drawable.s0p3).into(image3);
Picasso.with(getActivity()).load(R.drawable.s0p4).into(image4);
Picasso.with(getActivity()).load(R.drawable.s0p5).into(image5);
Picasso.with(getActivity()).load(R.drawable.s0p6).into(image6);
Picasso.with(getActivity()).load(R.drawable.s0p7).into(image7);
Picasso.with(getActivity()).load(R.drawable.s0p8).into(image8);
Picasso.with(getActivity()).load(R.drawable.s0p9).into(image9);
Picasso.with(getActivity()).load(R.drawable.s0p10).into(image10);
}
});
return null;
}
@Override
protected void onPostExecute(Void event) {
progressBar.setVisibility(View.GONE);
}
}
}
Logcat:
07-12 17:03:32.838 17497-17581/appinventor.ai_itiel_maimon.Rubiks_cube E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: appinventor.ai_itiel_maimon.Rubiks_cube, PID: 17497
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.IllegalStateException: Method call should happen from the main thread.
at com.squareup.picasso.Utils.checkMain(Utils.java:136)
at com.squareup.picasso.RequestCreator.into(RequestCreator.java:615)
at com.squareup.picasso.RequestCreator.into(RequestCreator.java:601)
at appinventor.ai_itiel_maimon.Rubiks_cube.Intro$LoadImagesTask.doInBackground(Intro.java:68)
at appinventor.ai_itiel_maimon.Rubiks_cube.Intro$LoadImagesTask.doInBackground(Intro.java:36)
at android.os.AsyncTask.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
AsyncTask 背后的想法是 doInBackground 执行后台工作,然后您可以 return 一些东西将作为参数传递给在主线程中执行的 onPostExecute。 所以尝试从 onPostExecute() 方法设置图像 :) 但是你可以在不使用 AsyncTask 的情况下轻松地做到这一点,就像这样:
public class BlankFragment extends Fragment {
private ImageView imv1;
private ImageView imv2;
private ImageView imv3;
private ImageView imv4;
private ImageView imv5;
private ImageView imv6;
private ImageView imv7;
private ImageView imv8;
private ImageView imv9;
ProgressDialog progressDialog = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
imv1 = (ImageView) getActivity().findViewById(R.id.imageView);
imv2 = (ImageView) getActivity().findViewById(R.id.imageView2);
imv3 = (ImageView) getActivity().findViewById(R.id.imageView3);
imv4 = (ImageView) getActivity().findViewById(R.id.imageView4);
imv5 = (ImageView) getActivity().findViewById(R.id.imageView5);
imv6 = (ImageView) getActivity().findViewById(R.id.imageView6);
imv7 = (ImageView) getActivity().findViewById(R.id.imageView7);
imv8 = (ImageView) getActivity().findViewById(R.id.imageView8);
imv9 = (ImageView) getActivity().findViewById(R.id.imageView9);
}
private void setImage() {
// show progress dialog
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
// set your images here.
}
});
// dismiss progressDialog here
}
}
如果您想得到一个好的答案,您应该 post 在这里添加一些代码。
一般来说,您可以简单地将可绘制对象用作 ImageView xml 实体中的 "android:src"(您在这里所做的几乎相同,只是使用此处的编程方法...)
或者在 Main\UI 线程上使用 Picasso(它与单独负责渲染 UI 组件的线程同名),即在 inflate 方法上。
一般来说,尝试检查更多 'how to' 使用片段和一般 android 设计模式的教程,你显然还在学习,但使用谷歌推荐的方法会更容易您的学习并最大限度地减少错误。