Help me on download multi-photos in a faster way.

Basic Tutorials concerning: GUI, Views, Activites, XML, Layouts, Intents, ...

Help me on download multi-photos in a faster way.

Postby seabookf_91 » Mon Oct 12, 2009 10:14 am

I am making a new app, which is simple enough to search all the related pics on the Picasa and display all these photoes on android.

I have encounterd an performance issue. The scenario is that sometimes there are lots of pics on the picasa and i could get all the pics source image url and use Bitmap bm = BitmapFactory.decodeStream(is) to get the pic and display all these on one GridView. Gridview isn't response before all the pics were downloaded from interenet.

I am thinking of using multi-thread to increase the downloading speed, however, the user interaction is still not good. We normally see all the black screen for a long time, then all the pics showed up.

When we making the Swing app, there are some swingworker thread in the background help you to do so, which is a good user experience.

Btw, Pic size is not the problem, since i could add some filter condition to control the pics' size.

Here is some code snippet i wrote:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. class PhotoAdapter extends BaseAdapter {
  3.  
  4.  
  5.  
  6.         private LayoutInflater mInflater;
  7.  
  8.         private List<Photo> mPhotos;
  9.  
  10.  
  11.  
  12.         public PhotoAdapter(Context context, List<Photo> photos) {
  13.  
  14.                 mInflater = LayoutInflater.from(context);
  15.  
  16.                 mPhotos = photos;
  17.  
  18.         }
  19.  
  20.  
  21.  
  22.         public int getCount() {
  23.  
  24.                 return mPhotos.size();
  25.  
  26.         }
  27.  
  28.  
  29.  
  30.         public Object getItem(int position) {
  31.  
  32.                 return position;
  33.  
  34.         }
  35.  
  36.  
  37.  
  38.         public long getItemId(int position) {
  39.  
  40.                 return position;
  41.  
  42.         }
  43.  
  44.  
  45.  
  46.         @Override
  47.  
  48.         public View getView(int position, View conView, ViewGroup par) {
  49.  
  50.                 ViewHolder holder;
  51.  
  52.  
  53.  
  54.                 if (conView == null) {
  55.  
  56.                         conView = mInflater.inflate(R.layout.photo, null);
  57.  
  58.                         holder = new ViewHolder();
  59.  
  60.                         holder.image = (ImageView)conView.findViewById(R.id.photo);
  61.  
  62. //                      holder.image.setLayoutParams(new GridView.LayoutParams(85, 85));
  63.  
  64. //                      holder.image.setScaleType(ImageView.ScaleType.CENTER_CROP);
  65.  
  66. //                      holder.image.setPadding(8, 8, 8, <img src="http://www.anddev.org/images/smilies/cool.png" alt="8)" title="Cool" />;
  67.  
  68.                         conView.setTag(holder);
  69.  
  70.                 } else {
  71.  
  72.                         holder = (ViewHolder) conView.getTag();
  73.  
  74.                 }
  75.  
  76.                 Photo photo = mPhotos.get(position);
  77.  
  78.                 URL url;
  79.  
  80.                 try {
  81.  
  82.                         url = new URL(photo.getThumbnailUrl());
  83.  
  84.                         URLConnection conn = url.openConnection();
  85.  
  86.                         conn.connect();
  87.  
  88.                         InputStream is = conn.getInputStream();
  89.  
  90.                         Bitmap bm = BitmapFactory.decodeStream(is);
  91.  
  92.                         holder.image.setImageBitmap(bm);
  93.  
  94.                 } catch (Exception e) {
  95.  
  96.                         e.printStackTrace();
  97.  
  98.                 }
  99.  
  100.                 return conView;
  101.  
  102.         }
  103.  
  104.  
  105.  
  106.         private class ViewHolder {
  107.  
  108.                 ImageView image;
  109.  
  110.         }
  111.  
  112.  
  113.  
  114. }
  115.  
  116.  
  117.  
  118. public class ShowPhotosActivity extends Activity {
  119.  
  120.  
  121.  
  122.         List<Photo> photos = null;
  123.  
  124.         String keyword = "";
  125.  
  126.  
  127.  
  128.         @Override
  129.  
  130.         protected void onCreate(Bundle savedInstanceState) {
  131.  
  132.                 super.onCreate(savedInstanceState);
  133.  
  134.                 setContentView(R.layout.showphotos);
  135.  
  136.  
  137.  
  138.                 GridView showPhotoGridView = (GridView) findViewById(R.id.showPhotoGridView);
  139.  
  140.  
  141.  
  142.                 Intent intent = this.getIntent();
  143.  
  144.                 Bundle bundle = intent.getExtras();
  145.  
  146.                 keyword = bundle.getString("keyword");
  147.  
  148.  
  149.  
  150.                 photos = getPhotos(keyword);
  151.  
  152.                 showPhotoGridView.setAdapter(new PhotoAdapter(this, photos));
  153.  
  154.                
  155.  
  156.                 showPhotoGridView.setOnItemClickListener(
  157.  
  158.                         new AdapterView.OnItemClickListener()
  159.  
  160.                     {
  161.  
  162.                       @Override
  163.  
  164.                       public void onItemClick(AdapterView<?> arg0,View arg1,
  165.  
  166.                                               int arg2,long arg3)
  167.  
  168.                       {
  169.  
  170.                         Intent intent = new Intent();
  171.  
  172.                         intent.setClass(ShowPhotosActivity.this, ShowPhotoActivity.class);
  173.  
  174.                         Bundle bundle = new Bundle();
  175.  
  176.                         bundle.putString("photoUrl",photos.get(arg2).getUrl());
  177.  
  178.                         intent.putExtras(bundle);
  179.  
  180.                         startActivity(intent);
  181.  
  182.                       }
  183.  
  184.                     });
  185.  
  186.         }
  187.  
  188.  
  189.  
  190.         private List<Photo> getPhotos(String keyword) {
  191.  
  192.  
  193.  
  194.                 System.setProperty("http.proxyHost", "10.254.144.158");
  195.  
  196.                 System.setProperty("http.proxyPort", "8080");
  197.  
  198.                 List<Photo> photos = null;
  199.  
  200.                 String path = "http://picasaweb.google.com/data/feed/api/all?kind=photo&q=" + keyword + "&max-results=9&imgmax=512&thumbsize=64";
  201.  
  202.                 URL url = null;
  203.  
  204.                 try {
  205.  
  206.                         url = new URL(path);
  207.  
  208.                         PhotoXmlHandler handler = new PhotoXmlHandler();
  209.  
  210.                         Xml.parse(url.openConnection().getInputStream(),
  211.  
  212.                                         Xml.Encoding.UTF_8, handler);
  213.  
  214.                         photos = handler.getPhotos();
  215.  
  216.                 } catch (Exception e) {
  217.  
  218.                         throw new RuntimeException(e);
  219.  
  220.                 }
  221.  
  222.                 return photos;
  223.  
  224.         }
  225.  
  226.  
  227.  
  228.         @Override
  229.  
  230.         protected void onStart() {
  231.  
  232.                 super.onStart();
  233.  
  234.         }
  235.  
  236.  
  237.  
  238.         @Override
  239.  
  240.         protected void onRestart() {
  241.  
  242.                 super.onRestart();
  243.  
  244.         }
  245.  
  246.  
  247.  
  248.         @Override
  249.  
  250.         protected void onResume() {
  251.  
  252.                 super.onResume();
  253.  
  254.         }
  255.  
  256.  
  257.  
  258.         @Override
  259.  
  260.         protected void onPause() {
  261.  
  262.                 super.onPause();
  263.  
  264.         }
  265.  
  266.  
  267.  
  268.         @Override
  269.  
  270.         protected void onStop() {
  271.  
  272.                 super.onStop();
  273.  
  274.         }
  275.  
  276.  
  277.  
  278.         @Override
  279.  
  280.         protected void onDestroy() {
  281.  
  282.                 super.onDestroy();
  283.  
  284.         }
  285.  
  286. }
  287.  
  288.  
Parsed in 0.045 seconds, using GeSHi 1.0.8.4



Please help on this. Thanks in advance.
Keep doing the things.
seabookf_91
Freshman
Freshman
 
Posts: 5
Joined: Mon Oct 12, 2009 9:26 am

Top

Postby seabookf_91 » Tue Oct 13, 2009 4:04 pm

I did some research to solve the problem, but it still doesn't work well. I need some help to understand the point.
Any heros or heroines could stand out to save the world?

Here is some demo code trying to solve the problem, but it may not the right one.
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. public class GridViewMultiThread extends Activity {
  3.  
  4.         Button button = null;
  5.  
  6.         GridView gridView = null;
  7.  
  8.         Context context = null;
  9.  
  10.         ImageAdapter imageAdapter;
  11.  
  12.         private View mSearchPanel;
  13.  
  14.         DownloadPhotosTask downloadPhotosTask;
  15.  
  16.  
  17.  
  18.         /** Called when the activity is first created. */
  19.  
  20.         @Override
  21.  
  22.         public void onCreate(Bundle savedInstanceState) {
  23.  
  24.                 super.onCreate(savedInstanceState);
  25.  
  26.                 setContentView(R.layout.main);
  27.  
  28.  
  29.  
  30.                 gridView = (GridView) findViewById(R.id.showPhotoGridView);
  31.  
  32.                
  33.  
  34.                 imageAdapter = new ImageAdapter(this);
  35.  
  36.                 gridView.setAdapter(imageAdapter);
  37.  
  38.                 downloadPhotosTask = (DownloadPhotosTask) new DownloadPhotosTask().execute();
  39.  
  40. //              button.setOnClickListener(new OnClickListener() {
  41.  
  42. //                      @Override
  43.  
  44. //                      public void onClick(View v) {
  45.  
  46. //                              button.setEnabled(false);
  47.  
  48. //                              downloadPhotosTask = (DownloadPhotosTask) new DownloadPhotosTask()
  49.  
  50. //                                              .execute();
  51.  
  52. //                      }
  53.  
  54. //              });
  55.  
  56.         }
  57.  
  58.  
  59.  
  60.         class DownloadPhotosTask extends AsyncTask<Void, Photo, Void> implements
  61.  
  62.                         PhotoDownloadListener {
  63.  
  64.  
  65.  
  66. //              @Override
  67.  
  68. //              protected void onPreExecute() {
  69.  
  70. //                      if (mSearchPanel == null) {
  71.  
  72. //                              mSearchPanel = ((ViewStub) findViewById(R.id.stub_search))
  73.  
  74. //                                              .inflate();
  75.  
  76. //
  77.  
  78. //                              ProgressBar progress = (ProgressBar) mSearchPanel
  79.  
  80. //                                              .findViewById(R.id.progress);
  81.  
  82. //                              progress.setIndeterminate(true);
  83.  
  84. //
  85.  
  86. //                              ((TextView) mSearchPanel.findViewById(R.id.label_loading))
  87.  
  88. //                                              .setText("loading");
  89.  
  90. //
  91.  
  92. //                              final View cancelButton = mSearchPanel
  93.  
  94. //                                              .findViewById(R.id.button_cancel);
  95.  
  96. //                              cancelButton.setOnClickListener(new View.OnClickListener() {
  97.  
  98. //                                      public void onClick(View v) {
  99.  
  100. //                                              onCancelSearch();
  101.  
  102. //                                      }
  103.  
  104. //                              });
  105.  
  106. //                      }
  107.  
  108. //              }
  109.  
  110.  
  111.  
  112. //              private void onCancelSearch() {
  113.  
  114. //                      if (downloadPhotosTask != null
  115.  
  116. //                                      && downloadPhotosTask.getStatus() == AsyncTask.Status.RUNNING) {
  117.  
  118. //                              downloadPhotosTask.cancel(true);
  119.  
  120. //                              downloadPhotosTask = null;
  121.  
  122. //                      }
  123.  
  124. //              }
  125.  
  126.  
  127.  
  128.                 @Override
  129.  
  130.                 protected Void doInBackground(Void... params) {
  131.  
  132.                         DownLoader.getInstance().downLoadImage(this);
  133.  
  134.                         return null;
  135.  
  136.                 }
  137.  
  138.  
  139.  
  140.                 @Override
  141.  
  142.                 public void onPhotoDownloadListener(Photo photo) {
  143.  
  144.                         if (photo != null && !isCancelled()) {
  145.  
  146.                                 publishProgress(photo);
  147.  
  148.                         }
  149.  
  150.                 }
  151.  
  152.  
  153.  
  154.                 @Override
  155.  
  156.                 public void onProgressUpdate(Photo... photos) {
  157.  
  158.                         for (Photo photo : photos) {
  159.  
  160.                                 imageAdapter.addPhoto(photo);
  161.  
  162.                                 gridView.invalidateViews();
  163.  
  164. //                              imageAdapter.registerDataSetObserver(observer)
  165.  
  166.                         }
  167.  
  168.                 }
  169.  
  170.  
  171.  
  172.         }
  173.  
  174.  
  175.  
  176. }
  177.  
  178.  
  179.  
  180. class ImageAdapter extends BaseAdapter {
  181.  
  182.  
  183.  
  184.         private Context mContext;
  185.  
  186.         private List<Photo> photos = new ArrayList<Photo>();
  187.  
  188.  
  189.  
  190.         public ImageAdapter(Context context) {
  191.  
  192.                 this.mContext = context;
  193.  
  194.         }
  195.  
  196.  
  197.  
  198.         public void addPhoto(Photo photo) {
  199.  
  200.                 photos.add(photo);
  201.  
  202.         }
  203.  
  204.  
  205.  
  206.         @Override
  207.  
  208.         public int getCount() {
  209.  
  210.                 return photos.size();
  211.  
  212.         }
  213.  
  214.  
  215.  
  216.         @Override
  217.  
  218.         public Object getItem(int position) {
  219.  
  220.                 return photos.get(position);
  221.  
  222.         }
  223.  
  224.  
  225.  
  226.         @Override
  227.  
  228.         public long getItemId(int position) {
  229.  
  230.                 return position;
  231.  
  232.         }
  233.  
  234.  
  235.  
  236.         @Override
  237.  
  238.         public View getView(int position, View convertView, ViewGroup parent) {
  239.  
  240.                 final ImageView imageView;
  241.  
  242.                 if (convertView == null) {
  243.  
  244.                         imageView = new ImageView(mContext);
  245.  
  246.                 } else {
  247.  
  248.                         imageView = (ImageView) convertView;
  249.  
  250.                 }
  251.  
  252.                 imageView.setImageBitmap(photos.get(position).getBm());
  253.  
  254.                 return imageView;
  255.  
  256.         }
  257.  
  258.  
  259.  
  260. }
  261.  
  262.  
  263.  
  264. class DownLoader {
  265.  
  266.         private static DownLoader downloader = new DownLoader();
  267.  
  268.         private static String[] myImageURL = null;
  269.  
  270.         private List<Photo> photos = new ArrayList<Photo>();
  271.  
  272.  
  273.  
  274.         public static DownLoader getInstance() {
  275.  
  276.                 initImageURL();
  277.  
  278.                 return downloader;
  279.  
  280.         }
  281.  
  282.  
  283.  
  284.         static void initImageURL() {
  285.  
  286.                 int no = 0;
  287.  
  288.                 myImageURL = new String[100];
  289.  
  290.                 for (int i = 0; i < myImageURL.length; i++) {
  291.  
  292.                         myImageURL[i] = "http://cp.a8.com/image/128X128GIF/8" + no + ".gif";
  293.  
  294.                         no++;
  295.  
  296.                         if (no % 10 == 0) {
  297.  
  298.                                 no = 0;
  299.  
  300.                         }
  301.  
  302.                 }
  303.  
  304.         }
  305.  
  306.  
  307.  
  308.         public List<Photo> downLoadImage(PhotoDownloadListener listener) {
  309.  
  310.                 List<String> urls = Arrays.asList(myImageURL);
  311.  
  312.                 List<Photo> photos = new ArrayList<Photo>();
  313.  
  314.                 URL aryURI = null;
  315.  
  316.                 URLConnection conn = null;
  317.  
  318.                 InputStream is = null;
  319.  
  320.                 Bitmap bm = null;
  321.  
  322.                 Photo photo = null;
  323.  
  324.                 for (String url : urls) {
  325.  
  326.                         // Log.e("URL:", url);
  327.  
  328.                         try {
  329.  
  330.                                 aryURI = new URL(url);
  331.  
  332.                                 conn = aryURI.openConnection();
  333.  
  334.                                 is = conn.getInputStream();
  335.  
  336.                                 bm = BitmapFactory.decodeStream(is);
  337.  
  338.                                 photo = new Photo(bm);
  339.  
  340.                                 listener.onPhotoDownloadListener(photo);
  341.  
  342.                                 photos.add(photo);
  343.  
  344.                         } catch (Exception e) {
  345.  
  346.                                 throw new RuntimeException(e);
  347.  
  348.                         } finally {
  349.  
  350.                                 try {
  351.  
  352.                                         if (is != null)
  353.  
  354.                                                 is.close();
  355.  
  356.                                 } catch (IOException e) {
  357.  
  358.                                         e.printStackTrace();
  359.  
  360.                                 }
  361.  
  362.                         }
  363.  
  364.                 }
  365.  
  366.                 return photos;
  367.  
  368.         }
  369.  
  370. }
  371.  
  372.  
  373.  
  374. class Photo {
  375.  
  376.         private Bitmap bm;
  377.  
  378.  
  379.  
  380.         public Photo(Bitmap bm) {
  381.  
  382.                 this.bm = bm;
  383.  
  384.         }
  385.  
  386.  
  387.  
  388.         public Bitmap getBm() {
  389.  
  390.                 return bm;
  391.  
  392.         }
  393.  
  394.  
  395.  
  396.         public void setBm(Bitmap bm) {
  397.  
  398.                 this.bm = bm;
  399.  
  400.         }
  401.  
  402.  
  403.  
  404.         interface PhotoDownloadListener {
  405.  
  406.                 public void onPhotoDownloadListener(Photo photo);
  407.  
  408.         }
  409.  
  410.  
  411.  
  412. }
  413.  
  414.  
Parsed in 0.051 seconds, using GeSHi 1.0.8.4
Keep doing the things.
seabookf_91
Freshman
Freshman
 
Posts: 5
Joined: Mon Oct 12, 2009 9:26 am

Fixed

Postby seabookf_91 » Wed Oct 14, 2009 6:54 am

Actually I searched all the related posts on the Android Community, there are some similar problems. And I tried a couple of hours to fix the problem, at lease I think it was fixed, though I am not exactly sure it’s a good solution.

Like I assumed that the problem is happened on gridView.invalidateViews(); I simply changed this into imageAdapter.notifyDataSetChanged(). And it works.
Keep doing the things.
seabookf_91
Freshman
Freshman
 
Posts: 5
Joined: Mon Oct 12, 2009 9:26 am

Top

Return to Novice Tutorials

Who is online

Users browsing this forum: No registered users and 3 guests