滚动查看和内存泄漏

时间:2013-11-29 20:46:30

标签: android memory-leaks scrollview out-of-memory

我的滚动视图中存在内存问题。我有一个新闻列表,以及显示完整新闻信息的活动。这是我的布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/lightgrey"
    android:paddingBottom="8dp"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"
    android:paddingTop="8dp"
    tools:context=".ViewNewsActivity" >

<ScrollView
    android:id="@+id/scroll_news"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:background="@color/lightgrey"
    android:isScrollContainer="false" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <ImageView
            android:id="@+id/ivIconFull"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/icon_bg"
            android:src="@drawable/nophotobig_hdpi_two" />

        <TextView
            android:id="@+id/tv_news_title_full"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="0.20"
            android:background="@color/dark_grey_one"
            android:paddingBottom="8dp"
            android:paddingLeft="12dp"
            android:paddingRight="8dp"
            android:paddingTop="8dp"
            android:text="@string/example_title"
            android:textColor="@color/white"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/tv_news_date_full"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/dark_grey_one"
            android:paddingBottom="8dp"
            android:paddingLeft="12dp"
            android:paddingRight="8dp"
            android:paddingTop="8dp"
            android:text="@string/example_date"
            android:textColor="@color/lightgrey"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/tv_news_text_full"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:background="@color/white"
            android:paddingBottom="8dp"
            android:paddingLeft="12dp"
            android:paddingRight="8dp"
            android:paddingTop="8dp"
            android:text="@string/example_title"
            android:textColor="@color/dark_grey_one"
            android:textSize="16sp" />

        <LinearLayout
            android:id="@+id/llVideo"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:background="@color/lightgrey"
            android:orientation="vertical" />

        <FrameLayout
            android:id="@+id/fragment_photo_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:background="@color/lightgrey" />

        <Button
            android:id="@+id/btn_write_comennts"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="20dp"
            android:background="@drawable/btn_green"
            android:onClick="onWriteCommentClick"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            android:text="@string/write_comment"
            android:textColor="@color/white" />

        <FrameLayout
            android:id="@+id/fragment_comments_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:background="@color/lightgrey" />

        <Button
            android:id="@+id/btn_read_comennts"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginBottom="8dp"
            android:layout_marginTop="20dp"
            android:background="@drawable/btn_gray"
            android:onClick="onReadCommentClick"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            android:text="@string/all_comments"
            android:textColor="@color/white" />
    </LinearLayout>
</ScrollView>

</RelativeLayout>

这是活动类

public class ViewNewsActivity extends SherlockFragmentActivity {
News news;
Context ctx;
Button btnReadComment;
int commentsCount;
double k;
boolean isTablet;
ScrollView scroll;
ImageView ivIcon;
Picasso picasso;
SherlockFragment frag;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (Build.VERSION.SDK_INT < 14) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
    }
    setTheme(R.style.Theme_CIS_NORMAL);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    setContentView(R.layout.activity_view_news);
    Gson gson = new Gson();
    Type newsType = new TypeToken<News>() {
    }.getType();
    news = gson.fromJson(getIntent().getStringExtra(AppConst.CHOOSEN_NEWS),
            newsType);
    // Set title style------------------------------

    SpannableString title = new SpannableString(news.getName());
    title.setSpan(new TypefaceSpan(this, "robotregular"), 0,
            title.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

    // ----------------------------------------------------------------
    getSupportActionBar().setTitle(title);
    // getSupportActionBar().setIcon(R.drawable.ic_ab);
    getSupportActionBar().setHomeButtonEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    ctx = this;
    isTablet = getResources().getBoolean(R.bool.isTablet);
    BusProvider.getInstance().register(this);
    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);
    FragmentHelper fHelper = new FragmentHelper(
            (SherlockFragmentActivity) ctx);
    int w = metrics.widthPixels;
    k = 8 * DeviceDensity.getDensity(ctx);

    // init all components
    commentsCount = news.getCommentsCount();
    scroll = (ScrollView) findViewById(R.id.scroll_news);
    scroll.clearDisappearingChildren();
    ivIcon = (ImageView) findViewById(R.id.ivIconFull);
    TextView tvTitle = (TextView) findViewById(R.id.tv_news_title_full);
    TextView tvDate = (TextView) findViewById(R.id.tv_news_date_full);
    TextView tvText = (TextView) findViewById(R.id.tv_news_text_full);
    // new FullImageLoader(ivIcon).execute(news.getSmallIcon());
    Picasso.Builder builder = new Picasso.Builder(ctx);
    picasso = builder.build();
    picasso.load(news.getSmallIcon())
            .placeholder(
                    PlaceHolders.getInstanse().getPlaceHolder(
                            (int) (w - (k * 2)),
                            (int) ((w - (k * 2)) / 1.5)))

            .error(PlaceHolders.getInstanse().getPlaceHolder(
                    (int) (w - (k * 2)), (int) ((w - (k * 2)) / 1.5)))
            .resize((int) (w - (k * 2)), (int) ((w - (k * 2)) / 1.5))
            .into(ivIcon);
    tvTitle.setTypeface(TypefaceCache.get(getAssets(),
            "fonts/robotregular.ttf"));
    tvTitle.setText(news.getName());
    tvDate.setTypeface(TypefaceCache.get(getAssets(),
            "fonts/robotregular.ttf"));
    tvDate.setText(news.getDate() + " / " + news.getCatName());
    tvText.setTypeface(TypefaceCache.get(getAssets(),
            "fonts/robotregular.ttf"));
    tvText.setText((news.getText()).replaceAll("&quot;", "\""));
    if (news.isNewsWithVideo()) {
        LinearLayout videoContainer = (LinearLayout) findViewById(R.id.llVideo);
        LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View video = inflater.inflate(R.layout.video, null);
        ImageView videoIcon = (ImageView) video
                .findViewById(R.id.ivVideoContainer);
        ImageButton btnPlay = (ImageButton) video
                .findViewById(R.id.ibPlayVideo);
        btnPlay.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                startActivity(new Intent(ViewNewsActivity.this,
                        YouTubeActivity.class).putExtra(AppConst.VIDEO_ID,
                        news.getVideoId()));
            }
        });
        picasso.load(
                "http://img.youtube.com/vi/" + news.getVideoId() + "/0.jpg")
                .placeholder(
                        PlaceHolders.getInstanse().getPlaceHolder(
                                (int) (w - (k * 2)),
                                (int) ((w - (k * 2)) / 1.5)))
                .error(PlaceHolders.getInstanse().getPlaceHolder(
                        (int) (w - (k * 2)), (int) ((w - (k * 2)) / 1.5)))
                .resize((int) (w - (k * 2)), (int) ((w - (k * 2)) / 1.5))
                .into(videoIcon);
        videoContainer.addView(video);
    }
    // --------------------------------------------------------------

    if (news.isNewsWithPhoto()) {



        if (news.getPhotoUrls().size() > 4) {

            frag = new NewsPhotoFragment();

        } else {
            if ((isTablet || Math.round(DeviceDensity.getInches(ctx)) >= 5)
                    && news.getPhotoUrls().size() > 1) {
                frag = new NewsAlbumListBigFragment();
            } else {
                frag = new NewsAlbumListFragment();
            }
        }
        Bundle b = new Bundle();
        b.putStringArrayList(AppConst.PHOTO_ALBUM,
                (ArrayList<String>) news.getPhotoUrls());
        fHelper.addFragmentWhithBundle(R.id.fragment_photo_container, frag,
                b);
    }

    // ----------------------------------------------------------------
    btnReadComment = (Button) findViewById(R.id.btn_read_comennts);
    if (news.isNewsCommented()) {
        if (commentsCount >= 5) {
            btnReadComment.setText(getResources().getString(
                    R.string.all_comments)
                    + " (" + news.getCommentsCount() + ")");
        } else {
            btnReadComment.setVisibility(Button.GONE);
        }

        Bundle b = new Bundle();
        CommentsFragment cFrag = new CommentsFragment();
        b.putString(AppConst.API_COMMENTS_PAGE_ID,
                Long.toString(news.getId()));
        fHelper.addFragmentWhithBundle(R.id.fragment_comments_container,
                cFrag, b);
    } else {
        Button btnWriteComment = (Button) findViewById(R.id.btn_write_comennts);

        btnWriteComment.setVisibility(Button.GONE);
        btnReadComment.setVisibility(Button.GONE);
    }

}

@Override
public void onDestroy() {
    super.onDestroy();
    scroll.removeAllViews();
    news = null;
    picasso.shutdown();
    picasso = null;
    ctx = null;
    frag = null;
    System.gc();

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    menu.add(0, AppConst.SHARE_ID, Menu.NONE, "Поделиться")
            .setIcon(R.drawable.ic_share_x)

            .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
    if (news.isNewsCommented() && commentsCount >= 5) {
        menu.add(0, AppConst.COMMENTS_ID, Menu.NONE, "Коментарии")
                .setIcon(R.drawable.chat_x)

                .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
    }
    return true;
}

// press action bar menu items
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getItemId() == android.R.id.home) {
        finish();
    } else if (item.getItemId() == AppConst.SHARE_ID) {
        final Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("text/plain");
        intent.setAction(Intent.ACTION_SEND);
        intent.putExtra(Intent.EXTRA_TEXT,
                news.getName() + " " + news.getNewsUrl());

        startActivity(Intent.createChooser(intent,
                getString(R.string.shareNews)));
    } else if (item.getItemId() == AppConst.COMMENTS_ID) {
        startActivity(new Intent(ViewNewsActivity.this,
                AllCommentsActivity.class).putExtra(AppConst.NEWS_ID,
                news.getId()).putExtra(AppConst.CHOOSEN_NEWS,
                news.getName()));
    }
    return true;
}

public void onWriteCommentClick(View v) {
    // write comments activity
    startActivity(new Intent(ViewNewsActivity.this,
            WriteCommentActivity.class).putExtra(AppConst.NEWS_ID,
            news.getId()).putExtra(AppConst.CALLED_FROM,
            AppConst.COMMENTS_FROM_VIEW_NEWS));
}

public void onReadCommentClick(View v) {
    // read all comments activity
    startActivity(new Intent(ViewNewsActivity.this,
            AllCommentsActivity.class).putExtra(AppConst.NEWS_ID,
            news.getId()).putExtra(AppConst.CHOOSEN_NEWS, news.getName()));
}

@SuppressLint("NewApi")
@Subscribe
public void onShouldUpdateCommentsCount(OnShouldUpdateCommentsInNews event) {
    commentsCount++;
    if (commentsCount >= 5) {
        btnReadComment.setVisibility(Button.VISIBLE);
        btnReadComment.setText(getResources().getString(
                R.string.all_comments)
                + " (" + commentsCount + ")");
        invalidateOptionsMenu();
    }
}
}

我试图清除一切,但我的记忆却像地狱一样长大!在我完成此活动之后,内存不会清除,很快我就会出现内存异常!

我真的不知道自己要做什么!也许我应该使用其他东西而不是滚动视图?

2 个答案:

答案 0 :(得分:0)

Here's这是一篇非常有用的文章,它描述了MAT - 一种可以帮助您在应用程序中查找内存泄漏的工具。

  

Dalvik运行时可能是垃圾收集的,但这并不意味着您可以忽略内存管理。您应该特别注意移动设备上的内存使用情况,因为内存受到更多限制。在本文中,我们将介绍Android SDK中的一些内存分析工具,它们可以帮助您减少应用程序的内存使用量。

答案 1 :(得分:0)

我非常确定您的内存泄漏与您尝试下载的视频图像的图像有关。你需要实现某种懒惰的图像加载器。只需谷歌这个术语,你会发现一两个图书馆为你做这一切。