通过Picasso加载图像时的java.lang.OutOfMemoryError

时间:2015-08-22 03:26:09

标签: android picasso image-loading

当我通过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,以前存储为GSON.jar转换的JSON字符串,稍后需要时转为ArrayList<MovieInfoModel>(通过GSON.jar)。应该如何存储这么大的文件?
如果有人需要,我会发布我的MovieReviewModel课程:

public class MovieReviewModel implements Parcelable {

private String reviewAuthor;
private String reviewContent;
private String reviewUrl;

constructors
setters
getters
Parcelable implementations
}

1 个答案:

答案 0 :(得分:3)

对我来说有同样的问题

.memoryPolicy(MemoryPolicy.NO_STORE)

工作,例如

    Picasso.with(getActivity()).load(backdropURL).memoryPolicy(MemoryPolicy.NO_STORE).centerCrop().fit().into(backdropView);