【发布时间】:2014-12-17 05:10:29
【问题描述】:
我确实在这个问题上工作过,但找不到解决方案,期待这种不自然的方式https://stackoverflow.com/a/2866717/2008040
我有一个从我的主要活动开始的活动 (WebViewActivityForHeadlines),该活动包含一个自定义视图寻呼机(当我使用标准视图寻呼机时会发生相同的行为)并且此视图寻呼机会膨胀自定义可缩放图像视图(当我使用标准图像视图)。
你可以在下面找到活动代码,我只是剪掉了一些不相关的部分。
@Fullscreen
@EActivity(R.layout.activity_web_view_for_headlines)
public class WebViewActivityForHeadlines extends BaseActivity
{
/** The log tag. */
private static final String LOG_TAG = WebViewActivityForHeadlines.class.getSimpleName();
private static int NUM_PAGES;
private static String CURRENT_URL = "";
private static String CURRENT_TITLE = "";
HeadlineListAdapter headlineListAdapter = GazetelikApplication.headlineListAdapter;
@ViewById(R.id.mPager)
public static JazzyViewPager MPAGER;
PagerAdapter mPagerAdapter;
@Bean
GazetelikSharingHelper gazetelikSharingHelper;
@ViewById
Button webViewButtonBack;
@ViewById
Button webViewButtonForward;
@ViewById
Button webViewButtonHome;
@ViewById
Button webViewButtonHide;
@ViewById
Button webViewButtonShare;
@ViewById
Button webViewButtonClose;
@ViewById(R.id.webViewControlPanel)
RelativeLayout controlPanel;
@ViewById(R.id.upperLayout)
RelativeLayout upperLayout;
@ViewById(R.id.mainRelativeLayout)
RelativeLayout mainLayout;
@ViewById(R.id.webViewShowControlPanelPanel)
RelativeLayout showControlPanelPanel;
Boolean isFirstRun = true;
Integer orderIdOfStart = null;
String tinyUrlString = "";
boolean isTinyUrlReady;
int tinyUrlCount;
// ProgressDialog mProgressDialog;
/** The view to show the ad. */
private AdView adView;
final Activity thisActivity = this;
DisplayImageOptions options;
Resources res;
@SuppressLint("NewApi")
@AfterViews
void afterViews()
{
NUM_PAGES = headlineListAdapter.getCount();
Intent thisIntent = getIntent(); // gets the previously created intent
orderIdOfStart = thisIntent.getIntExtra("orderId", 0);
mPagerAdapter = new ImageAdapter();
MPAGER.setAdapter(mPagerAdapter);
MPAGER.setCurrentItem(orderIdOfStart);
MPAGER.setTransitionEffect(JazzyViewPager.TransitionEffect.Accordion);
View decorView = getWindow().getDecorView();
if (Build.VERSION.SDK_INT == 14 || Build.VERSION.SDK_INT == 15)
{
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
decorView.setSystemUiVisibility(uiOptions);
}
else if (Build.VERSION.SDK_INT >= 16)
{
if (Build.VERSION.SDK_INT >= 19)
{
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
decorView.setSystemUiVisibility(uiOptions);
getTemporaryCache().setWebViewControlPanelVisible(true);
}
else
{
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);
}
}
res = getResources();
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_launcher)
.showImageForEmptyUri(R.drawable.ic_launcher)
.cacheInMemory(false)
.build();
}
/** Called before the activity is destroyed. */
@Override
public void onDestroy()
{
try
{
upperLayout.removeAllViews();
mainLayout.removeAllViews();
mPagerAdapter = null;
MPAGER.removeAllViews();
}
catch (Exception e)
{
Toast.makeText(thisActivity, e.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
super.onDestroy();
}
@Click(R.id.webViewButtonBack)
void onButtonBackClick()
{
int desiredPage = MPAGER.getCurrentItem() - 1;
if (desiredPage < 0)
{
desiredPage = 0;
}
if (desiredPage > mPagerAdapter.getCount())
{
desiredPage = mPagerAdapter.getCount();
}
MPAGER.setCurrentItem(desiredPage);
}
@Click(R.id.webViewButtonForward)
void onButtonForwardClick()
{
int desiredPage = MPAGER.getCurrentItem() + 1;
if (desiredPage < 0)
{
desiredPage = 0;
}
if (desiredPage > mPagerAdapter.getCount())
{
desiredPage = mPagerAdapter.getCount();
}
MPAGER.setCurrentItem(desiredPage);
}
@Click(R.id.webViewButtonHome)
void onButtonHomeClick()
{
MPAGER.setCurrentItem(orderIdOfStart);
}
@Click(R.id.webViewButtonHide)
void onButtonHideClick()
{
upperLayout.removeView(controlPanel);
showControlPanelPanel.setVisibility(RelativeLayout.VISIBLE);
}
@Click(R.id.webViewButtonClose)
void onButtonCloseClick()
{
finish();
}
@Click(R.id.webViewButtonShare)
void onButtonShareClick()
{
...
}
@Background
void buildTinyUrl(String longUrl)
{
...
}
@UiThread
void onOtherShareButtonClickTask(String url)
{
...
}
@UiThread
void onFacebookShareButtonClickTask(String url)
{
...
}
@UiThread
void onTwitterShareButtonClickTask(String url)
{
...
}
@Click(R.id.webViewButtonShow)
void onButtonShowClick()
{
upperLayout.addView(controlPanel);
showControlPanelPanel.setVisibility(RelativeLayout.INVISIBLE);
}
@UiThread
void popupToast(String message)
{
if (message != null)
{
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
RelativeLayout layout = (RelativeLayout) findViewById(R.id.headlinesForAddRelativeLayout);
layout.removeView(adView);
if (adView != null)
{
// Destroy the AdView.
adView.destroy();
}
super.onConfigurationChanged(newConfig);
}
@Override
public void onBackPressed()
{
if (orderIdOfStart == MPAGER.getCurrentItem())
{
super.onBackPressed();
}
else if (MPAGER.getCurrentItem() > orderIdOfStart)
{
MPAGER.setCurrentItem(MPAGER.getCurrentItem() - 1);
}
else if (MPAGER.getCurrentItem() < orderIdOfStart)
{
MPAGER.setCurrentItem(MPAGER.getCurrentItem() + 1);
}
}
private class ImageAdapter extends PagerAdapter
{
private LayoutInflater inflater;
ImageAdapter()
{
inflater = LayoutInflater.from(thisActivity);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object)
{
container.removeView((View) object);
}
@Override
public int getCount()
{
return NUM_PAGES;
}
@Override
public Object instantiateItem(ViewGroup view, int position)
{
View imageLayout = inflater.inflate(R.layout.simple_image_view, view, false);
assert imageLayout != null;
final TouchImageView imageView = (TouchImageView) imageLayout.findViewById(R.id.image);
final ProgressBar spinner = (ProgressBar) imageLayout.findViewById(R.id.loading);
ImageLoader.getInstance().displayImage(headlineListAdapter.getItem(position).getUrl(), imageView, options, new SimpleImageLoadingListener()
{
@Override
public void onLoadingStarted(String imageUri, View view)
{
spinner.setVisibility(View.VISIBLE);
}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason)
{
String message = null;
switch (failReason.getType()) {
case IO_ERROR:
message = "Input/Output error";
break;
case DECODING_ERROR:
message = "Image can't be decoded";
break;
case NETWORK_DENIED:
message = "Downloads are denied";
break;
case OUT_OF_MEMORY:
message = "Out Of Memory error";
break;
case UNKNOWN:
message = "Unknown error";
break;
}
Toast.makeText(thisActivity, message, Toast.LENGTH_SHORT).show();
spinner.setVisibility(View.GONE);
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
{
spinner.setVisibility(View.GONE);
imageView.setZoom(1F);
}
});
view.addView(imageLayout, 0);
return imageLayout;
}
@Override
public boolean isViewFromObject(View view, Object object)
{
return view.equals(object);
}
@Override
public void restoreState(Parcelable state, ClassLoader loader)
{
}
@Override
public Parcelable saveState()
{
return null;
}
}
}
当我第一次开始这个活动时,我可以看到堆会增加一点,因为视图分页器会增加 3 个视图,当我在数十个图像之间导航时一切正常。我清楚地看到,当我完成这个活动时,系统不会释放内存,如果我一次又一次地开始这个活动,最终我会得到预期的 OOME。
这是 logcat 输出
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:623)
at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.decode(BaseImageDecoder.java:78)
at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:264)
at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:237)
at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:135)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856)
你们能帮我找出内存泄漏吗?
【问题讨论】:
标签: android android-viewpager android-lifecycle android-memory