当我通过Picasso将图像的ArrayList加载到平板电脑(Nexus7)的GridView中时,
Picasso.with(getActivity()).load(movie.getMovieImageUrl()).into(imageViewPosterImage);
我的应用因以下错误而崩溃。但是,我的应用程序在手机(LG G2)上运行良好。
我严重怀疑这是由于消耗了加载图像的记忆所致。尽管是通过Jar Picasso加载的,但平板电脑中的图像要比手机大得多。我该如何解决这个错误?
java.lang.OutOfMemoryError: Failed to allocate a 1196 byte allocation with 13527808 free bytes and 12MB until OOM; failed due to fragmentation (required continguous free 131072 bytes for a new buffer where largest contiguous free 65536 bytes)
at android.database.CursorWindow.nativeGetString(Native Method)
at android.database.CursorWindow.getString(CursorWindow.java:438)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
at nanodegree.udacity.leon.udacitypopularmovies.helper.DatabaseHelper.getAllMovieInfo(DatabaseHelper.java:156)
at nanodegree.udacity.leon.udacitypopularmovies.display.MainActivity.onCreate(MainActivity.java:70)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
事实证明,这不是问题,而是从SQLiteDatabase提取数据的问题。
public ArrayList<MovieInfoModel> getAllMovieInfo() {
Log.v(LOG_TAG, "getAllMovieInfo() executed.");
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<MovieInfoModel> allMovieInfoArrayList = new ArrayList<>();
String getAllMovieInfoQuery = "SELECT * FROM " + STORED_TABLE_NAME;
Cursor cursor = db.rawQuery(getAllMovieInfoQuery, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Gson gson = new Gson();
MovieInfoModel movieInfo = new MovieInfoModel();
movieInfo.setMovieId(cursor.getLong(cursor.getColumnIndex(MOVIE_ID)));
movieInfo.setMovieOriginalTitle(cursor.getString(cursor.getColumnIndex(MOVIE_ORIGINAL_TITLE)));
movieInfo.setMoviePlotSynopsis(cursor.getString(cursor.getColumnIndex(MOVIE_PLOT_SYNOPSIS)));
movieInfo.setMovieUserRating(cursor.getString(cursor.getColumnIndex(MOVIE_USER_RATING)));
movieInfo.setMovieReleaseDate(cursor.getString(cursor.getColumnIndex(MOVIE_RELEASE_DATE)));
ArrayList<String> movieTrailerUrlArrayList = gson.fromJson(cursor.getString(cursor.getColumnIndex(MOVIE_TRAILER_URL_JSON_STRING)), new TypeToken<ArrayList<String>>() {
}.getType());
movieInfo.setMovieTrailerUrlArrayList(movieTrailerUrlArrayList);
ArrayList<MovieReviewModel> movieReviewArrayList = gson.fromJson(cursor.getString(cursor.getColumnIndex(MOVIE_REVIEW_JSON_STRING)), new TypeToken<ArrayList<MovieReviewModel>>() {
}.getType());
movieInfo.setMovieReviewArrayList(movieReviewArrayList);
allMovieInfoArrayList.add(movieInfo);
}
return allMovieInfoArrayList;
}
错误行是
ArrayList<MovieReviewModel> movieReviewArrayList = gson.fromJson(cursor.getString(cursor.getColumnIndex(MOVIE_REVIEW_JSON_STRING)), new TypeToken<ArrayList<MovieReviewModel>>() {
}.getType());
可能是由于
movieReviewArrayList
太大引起的。 movieReviewArrayList
是MovieReviewModel(一个自定义对象)的ArrayList,以前存储为JSON字符串,由GSON.jar
转换,然后在需要时转换为ArrayList<MovieInfoModel>
(通过GSON.jar
)。应该如何存储这么大的文件?如果可能需要,我将发布我的
MovieReviewModel
类:public class MovieReviewModel implements Parcelable {
private String reviewAuthor;
private String reviewContent;
private String reviewUrl;
constructors
setters
getters
Parcelable implementations
}
最佳答案
对我来说有同样的问题
.memoryPolicy(MemoryPolicy.NO_STORE)
工作,例如
Picasso.with(getActivity()).load(backdropURL).memoryPolicy(MemoryPolicy.NO_STORE).centerCrop().fit().into(backdropView);