【发布时间】:2013-11-29 20:46:29
【问题描述】:
我的滚动视图出现记忆问题。我有一个新闻列表和显示完整新闻信息的活动。这是我的布局:
<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(""", "\""));
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();
}
}
}
我试图清除一切,但我的记忆像地狱一样长大!!!而且在我完成这个活动后,内存并没有清除,很快我就出现了内存不足的异常!
我真的不知道我要做什么!也许我应该使用其他东西而不是滚动视图?
【问题讨论】:
-
我会按照 Egor 的建议使用 MAT 查看堆转储。您似乎不是以传统方式使用毕加索,它可能与它有关。试试 Picasso.with(this).load(url).into(imageView);你可以将你的 .resize() 等链接在他们的.resize() 中。无需为它保留参考。
-
您可以尝试的一件事是制作 ctx = this.getApplicationContext() 并查看是否可以解决问题。内存泄漏是由于将 Activity 上下文从 Activity 传递给比 Activity 的生命周期更长的东西而引起的
-
我以这种方式使用 Picasso,没有任何帮助,我无法使用单例调用 picasso.shutdown()(此方法调用 memoryCache.clear()),所以我决定做这样的事情。我在我所有的适配器中都使用毕加索,我在网格视图和列表视图中下载了大量的图像,我没有任何问题,这就是为什么我认为问题出在滚动视图中。但我会尝试 MAT,也许它会有所帮助......
-
当然!我也会尝试,我的片段中有一个问题我使用来自 onAttach(Activity a){ctx = activity} 的上下文,我是否以正确的方式使用它?
-
如果 Fragment 以某种方式比 Activity 寿命更长,它肯定会导致整个 Activity 泄漏。主要问题之一是匿名类或内部类,它们的寿命可能比封闭类长。如果您在 Fragment 中有任何这些,请看那里。
标签: android memory-leaks scrollview out-of-memory