2013-06-18 3 views
0

Я частично следил за http://android-developers.blogspot.de/2010/07/multithreading-for-performance.html, чтобы загрузить изображения с URL-адреса и отобразить его в виде сетки. С статическим списком он работал хорошо.Загрузка изображений из динамического списка и отображения в GridView

Я пытаюсь получить некоторый URL-адрес в Интернете, проанализировав веб-страницу с помощью jsoup и создав свой собственный список URL-адресов. Программа просто сработает при запуске.

public class MainGridActivity extends Activity { 

    private ImageAdapter mAdapter; 
    private Bitmap mPlaceHolder; 
    private String [] mMangaList = null; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main_grid); 

     downloadMangaImages(); 

     GridView gridView = (GridView) findViewById(R.id.gridView); 
     mAdapter = new ImageAdapter(this); 
     setLoadingImage(R.drawable.empty_photo); 

     gridView.setAdapter(mAdapter); 
    } 



    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main_grid, menu); 
     return true; 
    } 

    /** 
    * sets a place holder bitmap while the actual bitmap is loading 
    * 
    * @param resId 
    */ 
    public void setLoadingImage(int resId) { 
     mPlaceHolder = BitmapFactory.decodeResource(getResources(), resId); 
    } 

    public void downloadMangaImages() { 
     try { 
      Document doc = Jsoup.connect("http://mangafox.me/directory/").get(); 

      Element content = doc.getElementById("content"); 
      Elements links = content.getElementsByTag("img"); 

      mMangaList = new String[links.toArray().length]; 
      int i = 0; 
      for(Element link : links) { 
       mMangaList[i] = link.attr("src"); 
       i++; 
      } 

     } catch(IOException e) {} 

    } 


    private class ImageAdapter extends BaseAdapter { 
     private Context mContext; 
     public ImageAdapter (Context context) { 
      mContext = context; 
     } 



     @Override 
     public int getCount() { 
      return mMangaList.length; 
     } 

     @Override 
     public Object getItem(int position) { 
      return null; 
     } 

     @Override 
     public long getItemId(int position) { 
      return 0; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup container) { 
      ImageView imageView; 
      if(convertView == null) { 
       imageView = new ImageView(mContext); 
       imageView.setLayoutParams(new GridView.LayoutParams(200,300)); 
       imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
      } else { 
       imageView = (ImageView) convertView; 
      } 

      loadImageToView(mMangaList[position],imageView); 

      return imageView; 
     } 

    } 

    public void loadImageToView(String url, ImageView imageView) { 
     final BitmapWorkerTask task; 
     final TaskReference taskReference; 

     if(url == null) { 
      return; 
     } 

     else if(cancelPotentialWork(url, imageView)) { // tries to cancel previous tasks on this imageView if possible 
      task = new BitmapWorkerTask(imageView); 
      taskReference = new TaskReference(getResources(),task, mPlaceHolder); 
      imageView.setImageDrawable(taskReference); 
      task.execute(url); 

     } 
    } 

    private static boolean cancelPotentialWork (String url, ImageView imageView) { 
     BitmapWorkerTask previousTask = getBitmapWorkerTask(imageView); 

     if(previousTask != null) { 

      String previousUrl = previousTask.url; 

      if(previousUrl == null || !previousUrl.equals(url)) { 
       previousTask.cancel(true); 
      } else { 
       return false; // since task is already in progress, let it finish 
      } 
     } 

     return true; 
    } 

    private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { 
     if(imageView != null) { 
      final Drawable drawable = imageView.getDrawable(); 

      if(drawable instanceof TaskReference) { 
       return ((TaskReference) drawable).getBitmapWorkerTask(); 
      } 
     } 
     return null; 
    } 

    private class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> { 
     //Fields 
     private final WeakReference<ImageView> mImageViewReference; 
     private String url; 

     //constructors 
     public BitmapWorkerTask(ImageView imageView) { 
      mImageViewReference = new WeakReference<ImageView> (imageView); 
     } 

     //main body 
     @Override 
     protected Bitmap doInBackground(String ... urls) { //Image not found in memory cache so start processing image here 
      url = urls[0]; 
      return downloadBitmapFromURL(url); 

     } 


     @Override 
     protected void onPostExecute(Bitmap bitmap) { 
      if(isCancelled()) { 
       bitmap = null; 
      } 

      if(mImageViewReference != null) { 
       ImageView imageView = mImageViewReference.get(); 
       BitmapWorkerTask task = getBitmapWorkerTask(imageView); 
       if(this == task) { 
        imageView.setImageBitmap(bitmap); 
       } 

      } 


     } 

     public Bitmap downloadBitmapFromURL(String urlString) { 
      final int BUFFER_SIZE = 8 *1024; 
      HttpURLConnection conn = null; 
      InputStream is = null; 

      try { 
       final URL url = new URL(urlString); 
       conn = (HttpURLConnection) url.openConnection(); 
       is = new BufferedInputStream(conn.getInputStream(), BUFFER_SIZE); 


       return BitmapFactory.decodeStream(is); 

      } catch(IOException e) {} 

      finally { 
       if(conn != null) { 
        conn.disconnect(); 
       } 
       try { 
        if(is != null) { 
         is.close(); 
        } 

       } catch (IOException e) {} 

      } 

      return null; 
     } 
    } 


    private class TaskReference extends BitmapDrawable { 
     private final WeakReference<BitmapWorkerTask> mBitmapWorkerTaskReference; 

     public TaskReference(Resources res, BitmapWorkerTask task, Bitmap placeHolder) { 
      super(res, placeHolder); 
      mBitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(task); 
     } 

     public BitmapWorkerTask getBitmapWorkerTask(){ 
      return mBitmapWorkerTaskReference.get(); 
     } 
    } 

} 

LogCat

06-18 21:24:28.845: D/AbsListView(5721): Get MotionRecognitionManager 
06-18 21:24:28.865: D/AndroidRuntime(5721): Shutting down VM 
06-18 21:24:28.865: W/dalvikvm(5721): threadid=1: thread exiting with uncaught exception (group=0x40ccc2a0) 
06-18 21:24:28.870: E/AndroidRuntime(5721): FATAL EXCEPTION: main 
06-18 21:24:28.870: E/AndroidRuntime(5721): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gridviewtest/com.gridviewtest.MainGridActivity}: android.os.NetworkOnMainThreadException 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2100) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at android.app.ActivityThread.access$600(ActivityThread.java:140) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at android.os.Handler.dispatchMessage(Handler.java:99) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at android.os.Looper.loop(Looper.java:137) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at android.app.ActivityThread.main(ActivityThread.java:4898) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at java.lang.reflect.Method.invokeNative(Native Method) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at java.lang.reflect.Method.invoke(Method.java:511) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at dalvik.system.NativeStart.main(Native Method) 
06-18 21:24:28.870: E/AndroidRuntime(5721): Caused by: android.os.NetworkOnMainThreadException 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at java.net.InetAddress.lookupHostByName(InetAddress.java:385) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at java.net.InetAddress.getAllByName(InetAddress.java:214) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at libcore.net.http.HttpConnection.connect(HttpConnection.java:128) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:315) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at libcore.net.http.HttpEngine.connect(HttpEngine.java:310) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:289) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:239) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:425) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:410) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:164) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at org.jsoup.helper.HttpConnection.get(HttpConnection.java:153) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at com.gridviewtest.MainGridActivity.downloadMangaImages(MainGridActivity.java:71) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at com.gridviewtest.MainGridActivity.onCreate(MainGridActivity.java:42) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at android.app.Activity.performCreate(Activity.java:5206) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2064) 
06-18 21:24:28.870: E/AndroidRuntime(5721):  ... 11 more 
+1

Нам нужен отчет LogCat, чтобы увидеть, в чем проблема, вы можете разместить? –

ответ

0

Вы должны переместить downloadMangaImages(); метод в фоновом потоке. AsyncTask - лучший выбор для вас.

Нечто подобное (слепое кодирование):

String targetURL = .... 
new AsyncTask<String, Void, String[]>(){ 
protected String[] doInBackground(String ... args) { 
    try { 

      Document doc = Jsoup.connect("http://mangafox.me/directory/").get(); 

      Element content = doc.getElementById("content"); 
      Elements links = content.getElementsByTag("img"); 

      String[] mMangaList = new String[links.toArray().length]; 
      int i = 0; 
      for(Element link : links) { 
       mMangaList[i] = link.attr("src"); 
       i++; 
      } 
return mMangaList; 
     } catch(IOException e) {return null;} 
} 
protected void onPostExecute(String[] result) { 
if(result != null) { 
// create the adapter and load it in list 
} 
} 
}.execute(targetURL); 
+0

ahh я получил это спасибо – user2498337

Смежные вопросы