2015-11-19 2 views
2

У меня есть следующий фрагмент, который заполняет gridview растровыми изображениями из URL-адресов. Проблема в том, что я знаю, что это очень «тяжелая» работа и выполняется в потоке пользовательского интерфейса, поэтому она замедляет фрагмент при загрузке сетки.Как загрузить изображения GridView с помощью AsyncTask?

Я читал, что AsyncTask необходим для выполнения «тяжелой» работы в фоновом режиме, но я не могу найти ничего похожего на то, что я хочу.

public class HomeFragment extends Fragment { 

protected static final String TAG = null; 
public HomeFragment(){} 
GridView gridView; 
private GridViewAdapter gridAdapter; 
private SQLiteHandler db; 
private SwipeRefreshLayout swipeLayout; 
private ProgressDialog pDialog; 

GPSTracker gps; 
String uid; 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

    db = new SQLiteHandler(getActivity()); 
    gridAdapter = new GridViewAdapter(getActivity(), R.layout.grid_item_layout, getData()); 


    pDialog = new ProgressDialog(getActivity()); 
    pDialog.setCancelable(true); 

    uid="1"; 
    String email = db.getFromTable(getActivity(), "email", SQLiteHandler.TABLE_LOGIN, "WHERE _id="+uid); 
    String from_age = db.getFromTable(getActivity(), "from_age", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid); 
    String to_age = db.getFromTable(getActivity(), "to_age", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid); 
    String distance = db.getFromTable(getActivity(), "distance", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid); 
    String unit = db.getFromTable(getActivity(), "unit", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid); 
    String men = db.getFromTable(getActivity(), "men", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid); 
    String women = db.getFromTable(getActivity(), "women", SQLiteHandler.TABLE_SETTINGS, "WHERE uid="+uid); 

    fetchUsers(email, from_age, to_age, distance, unit, men, women); 

    final View rootView = inflater.inflate(R.layout.fragment_home, container, false); 


    //getActivity().getActionBar().setTitle(R.string.home); 

    gridView = (GridView) rootView.findViewById(R.id.gridView); 


    gridView.setAdapter(gridAdapter); 

    gridView.setOnItemClickListener(new OnItemClickListener() { 
     public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 
      ImageItem item = (ImageItem) parent.getItemAtPosition(position); 
      ImageView imageView = (ImageView) v.findViewById(R.id.image); 
      //Create intent 
      Intent intent = new Intent(getActivity(), DetailsActivity.class); 
      int[] screenLocation = new int[2]; 
      imageView.getLocationOnScreen(screenLocation); 
      intent.putExtra("left", screenLocation[0]). 
      putExtra("top", screenLocation[1]). 
      putExtra("width", imageView.getWidth()). 
      putExtra("height", imageView.getHeight()). 
      putExtra("uid", item.getUid()); 
      startActivity(intent); 
     } 
    }); 
    swipeLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_container); 
    swipeLayout.setOnRefreshListener(new OnRefreshListener() { 

     @Override 
     public void onRefresh() { 
      //my update process 
      Fragment currentFragment = getFragmentManager().findFragmentByTag("0"); 
      FragmentTransaction fragTransaction = getFragmentManager().beginTransaction(); 
      fragTransaction.detach(currentFragment); 
      fragTransaction.attach(currentFragment); 
      fragTransaction.commit(); 
     } 
    }); 

    return rootView; 
} 

// Prepare some dummy data for gridview 
private ArrayList<ImageItem> getData() { 
    final ArrayList<ImageItem> imageItems = new ArrayList<>(); 

    Cursor cursor = db.getAllRows("*", SQLiteHandler.TABLE_USERS, ""); 
    //Query local DB to initialize settings screen 

    for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()){ 
     String uid = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_UID)); 
     String name = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_NAME)); 
     String dob = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_DOB)); 
     //String gender = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_GENDER)); 
     String photourl = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_PHOTOURL)); 
     //String distance = cursor.getString(cursor.getColumnIndex(SQLiteHandler.KEY_DISTANCE)); 

     String[] birthdayArr = dob.split("-"); 

     int age = getAge(Integer.parseInt(birthdayArr[0]), Integer.parseInt(birthdayArr[1]), Integer.parseInt(birthdayArr[2])); 

     Bitmap bitmap = getBitmapFromURL(photourl); 

     imageItems.add(new ImageItem(bitmap, name+" - " + age, uid)); 
    } 
    return imageItems; 
} 


public static Bitmap getBitmapFromURL(String src) { 
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 

    StrictMode.setThreadPolicy(policy); 
    try { 
     URL url = new URL(src); 
     HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
     connection.setDoInput(true); 
     connection.connect(); 
     InputStream input = connection.getInputStream(); 
     Bitmap myBitmap = BitmapFactory.decodeStream(input); 
     return myBitmap; 
    } catch (IOException e) { 
     // Log exception 
     return null; 
    } 
} 

public int getAge(int year, int month, int day) { 
    //int nowMonth = now.getMonth()+1; 
    int nowMonth = Calendar.getInstance().get(Calendar.DAY_OF_MONTH); 
    //int nowYear = now.getYear()+1900; 
    int nowYear = Calendar.getInstance().get(Calendar.YEAR); 
    int result = nowYear - year; 

    if (month > nowMonth) { 
     result--; 
    } 
    else if (month == nowMonth) { 
     int nowDay = Calendar.getInstance().get(Calendar.DATE); 

     if (day > nowDay) { 
      result--; 
     } 
    } 
    return result; 
} 

private void showDialog() { 
    if (!pDialog.isShowing()) 
     pDialog.show(); 
} 

private void hideDialog() { 
    Log.i("hideDialog", "called"); 
    if (pDialog.isShowing()) 
     pDialog.dismiss(); 
} 

public void fetchUsers(final String email, final String agefrom, final String ageto, final String distance, final String distanceUnit, final String interested_men, final String interested_wmen){ 
    // Tag used to cancel the request 

    gps = new GPSTracker(getActivity()); 
    String tag_string_req = "req_login"; 
    pDialog.setMessage("Finding users ..."); 
    showDialog(); 

    StringRequest strReq = new StringRequest(Method.POST, 
      AppConfig.URL_LOGIN, new Response.Listener<String>() { 

       @Override 
       public void onResponse(String response) { 
        Log.d(TAG, "Fetch Response: " + response.toString()); 
        hideDialog(); 
        try { 
         JSONObject jObj = new JSONObject(response); 
         int success = jObj.getInt("success"); 
         JSONArray users = jObj.getJSONArray("users"); 

         // Check for error node in json 
         if (success == 1) { 

          //Log.i("success", users+""); 

          if (users.length() == 0) { 
           Toast.makeText(getActivity(), "No users found! \nPlease try again soon.", Toast.LENGTH_LONG).show(); 
           db.emptyTable(SQLiteHandler.TABLE_USERS); 
          }else{ 
           db.emptyTable(SQLiteHandler.TABLE_USERS); 
           for (int i = 0; i < users.length(); i++) { 
            JSONObject user = users.getJSONObject(i); 
            String uid = user.getString("uid"); 
            String name = user.getString("name"); 
            String dob = user.getString("dob"); 
            String gender = user.getString("gender"); 
            String photourl = user.getString("photoUrl"); 
            String distance = user.getString("distance"); 

            String[][] userValues = { 
              { SQLiteHandler.KEY_UID, uid}, 
              { SQLiteHandler.KEY_NAME, name}, 
              { SQLiteHandler.KEY_DOB, dob}, 
              { SQLiteHandler.KEY_GENDER, gender}, 
              { SQLiteHandler.KEY_PHOTOURL, photourl}, 
              { SQLiteHandler.KEY_DISTANCE, distance} 
            }; 
            db.insert(SQLiteHandler.TABLE_USERS, userValues); 
           } 
          } 
         } else { 
          // Error in login. Get the error message 
          String errorMsg = jObj.getString("error_msg"); 
          Toast.makeText(getActivity(),errorMsg, Toast.LENGTH_LONG).show(); 
         } 
        } catch (JSONException e) { 
         // JSON error 
         e.printStackTrace(); 
        } 

       } 
      }, new Response.ErrorListener() { 

       @Override 
       public void onErrorResponse(VolleyError error) { 
        Log.e(TAG, "Login Error: " + error.getMessage()); 
        Toast.makeText(getActivity(), 
          error.getMessage(), Toast.LENGTH_LONG).show(); 
        hideDialog(); 
       } 
      }) { 

     @Override 
     protected Map<String, String> getParams() { 
      // Posting parameters to login url 
      //$lat, $lng, $email, $agefrom, $ageto, $distance, $distanceUnit, $interested_men, $interested_wmen 
      Map<String, String> params = new HashMap<String, String>(); 
      params.put("tag", "login"); 
      params.put("lat", gps.getLatitude()+""); 
      params.put("lng", gps.getLongitude()+""); 
      params.put("email", email); 
      params.put("agefrom", agefrom); 
      params.put("ageto", ageto); 
      params.put("distance", distance); 
      params.put("distanceUnit", distanceUnit); 
      params.put("interested_men", interested_men+""); 
      params.put("interested_wmen", interested_wmen+""); 
      params.put("fetch", "y"); 
      Log.i(TAG, params+""); 
      return params; 
     } 

    }; 

    // Adding request to request queue 
    AppController.getInstance().addToRequestQueue(strReq, tag_string_req); 

} 
} 
+0

Если у вас есть роскошь использования сторонней библиотеки, Picasso сэкономит вам массу неприятностей. – fractalwrench

+1

Если вы не выполняете упражнение, чтобы узнать о очень сложных проблемах и управлении потоками и памятью, общий совет: просто используйте библиотеку, ничего хорошего не выйдет из попытки заново изобрести колесо. Поиск Пикассо или Глейд. – Budius

ответ

0

Как было предложен fractalwrench и Budius, Picasso был очень хорошим и очень простым решением для этого. Все, что мне нужно было сделать, это передать URL-адрес фотографии, а не весь BitMap, в мой адаптер GridView и использовать Picasso.with(context).load(item.getImage()).into(holder.image); для создания BitMap для просмотра изображения. Это было так просто реализовать и дает мне именно то, что мне нужно. Thaks

0

Как загрузить GridView изображения с AsyncTask?

Загрузка изображений в виде растрового изображения в HomeFragment. Используйте NetworkImageView от Volley в макете элемента GridView для загрузки изображений в GridView.

Вместо того, чтобы хранить Bitmap, хранить изображение url в ImageItem.

Смотрите следующий учебник для получения дополнительной помощи:

Using NetworkImageView

0

AsynTask класс

public class GridDataAsyncTask extends AsyncTask<GridDataAsyncTask.GridCallback, Void, GridAdapter> { 

public interface GridCallback { 
    void onAdapterReady(GridAdapter adapter); 
} 

private GridCallback mCallBack; 

@Override 
protected GridAdapter doInBackground(GridCallback... callbacks) { 
    mCallBack = callbacks[0]; 


    // TODO get data and create grid adapter 

    return adapter; 
} 

@Override 
protected void onPostExecute(GridAdapter gridAdapter) { 
    super.onPostExecute(gridAdapter); 
    mCallBack.onAdapterReady(gridAdapter); 
} 
} 

активность

public class GridActivity extends AppCompatActivity implements GridDataAsyncTask.GridCallback { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    new GridDataAsyncTask().execute(this); 
} 

@Override 
public void onAdapterReady(GridAdapter adapter) { 
    // TODO set adapte to GridView 
} 
} 
Смежные вопросы