如何使用AsyncTask加载GridView图像?

时间:2015-11-19 14:55:56

标签: android gridview android-asynctask

我在下面的片段下面用URL填充了一个带有Bitmaps的gridview。问题是我知道这是非常“繁重”的工作,并且在UI线程上完成,所以它在加载网格时减慢了碎片的速度。

我已经读到需要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);

}
}

4 个答案:

答案 0 :(得分:0)

  

如何使用AsyncTask加载GridView图像?

HomeFragment中将图像下载为位图。在GridView项目的布局中使用NetworkImageView中的Bitmap来在GridView中加载图像。

不是存储ImageItem,而是将图片网址存储在IncludeOptional "c:/wamp/vhosts/*"

有关更多帮助,请参阅以下教程:

Volley

答案 1 :(得分: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
}
}

答案 2 :(得分:0)

你能做的最好就是使用http://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html并制作一个lru缓存并将图像放在lru缓存中。 示例在android教程中给出 http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

答案 3 :(得分:0)

根据fractalwrenchBudius的建议,Picasso是一个非常好且非常简单的解决方案。我所要做的就是将照片网址而不是整个BitMap传递给我的GridView适配器,并使用Picasso.with(context).load(item.getImage()).into(holder.image);为图像视图创建BitMap。这很容易实现,并且完全符合我的需要。 Thaks