我在下面的片段下面用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);
}
}
答案 0 :(得分:0)
如何使用AsyncTask加载GridView图像?
在HomeFragment
中将图像下载为位图。在GridView项目的布局中使用NetworkImageView
中的Bitmap
来在GridView中加载图像。
不是存储ImageItem
,而是将图片网址存储在IncludeOptional "c:/wamp/vhosts/*"
。
有关更多帮助,请参阅以下教程:
答案 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)
根据fractalwrench和Budius的建议,Picasso是一个非常好且非常简单的解决方案。我所要做的就是将照片网址而不是整个BitMap传递给我的GridView适配器,并使用Picasso.with(context).load(item.getImage()).into(holder.image);
为图像视图创建BitMap。这很容易实现,并且完全符合我的需要。 Thaks