Mik*_*e B 10 android out-of-memory android-viewpager
我在StackOverflow和其他地方看到了类似于此的各种问题,但这些解决方案似乎都没有解决我的问题,如下所示:
我有一个带有简单PagerAdapter的ViewPager.每个"页面"都有一个与之关联的XML布局,其中包含至少一个TextView,一个ImageView,有时还包含另一个TextView.与ImageView相关联的图像在一维中通常为1000px而在另一维中较少,但它们是8位索引的Gif,因此它们都不比20kB大得多.我将它们设置为Drawables,然后适当缩小以适应分配给它们的空间.
只有6页.当我启动活动时,它工作正常,我甚至可以翻到最后一页,但如果我一直向右翻转然后一直向左翻转,我得到一个OutOfMemoryError.这对我来说没有意义,因为我认为ViewPager应该在超过1个屏幕之外销毁页面,并且我正在处理destroyItem(),如其他地方所建议的那样.
以下是PagerAdapter的代码:
package doop.doop.dedoop;
import doop.doop.dedoop.R.layout;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
public class HelpPagerAdapter extends PagerAdapter{
private Context applicationContext;
private Context activityContext;
public HelpPagerAdapter(Context appContext, Context activContext){
applicationContext = appContext;
activityContext = activContext;
}
public int getCount() {
return 6;
}
public Object instantiateItem(ViewGroup collection, int position) {
LayoutInflater inflater = (LayoutInflater) collection.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int resId = 0;
int ivId = 0;
int drawId = 0;
switch (position) {
case 0:
resId = R.layout.help1;
ivId = R.id.helpImage1;
drawId = R.drawable.left_col_highlight;
break;
case 1:
resId = R.layout.help2;
ivId = R.id.helpImage2;
drawId = R.drawable.right_col_highlight;
break;
case 2:
resId = R.layout.help3;
ivId = R.id.helpImage3;
drawId = R.drawable.p2win;
break;
case 3:
resId = R.layout.help4;
ivId = R.id.helpImage4;
drawId = R.drawable.first_move;
break;
case 4:
resId = R.layout.help5;
ivId = R.id.helpImage5;
drawId = R.drawable.screen_bottom;
break;
case 5:
resId = R.layout.help6;
ivId = R.id.helpImage6;
drawId = R.drawable.illegal_move;
break;
}
View view = inflater.inflate(resId, null);
collection.addView(view, 0);
if (ivId != 0 && drawId != 0) {
ImageView iv = (ImageView) view.findViewById(ivId);
iv.setImageDrawable(activityContext.getResources().getDrawable(drawId));
}
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == ((View) arg1);
}
}
Run Code Online (Sandbox Code Playgroud)
以下是其中一个页面布局的示例:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/helpPageLayout" >
<TextView
style="@style/helpText"
android:text="@string/help2" />
<ImageView android:id="@+id/helpImage2"
style="@style/helpImage" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
这是整个事情的活动:
package doop.doop.dedoop;
import android.app.Activity;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
public class Help extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_help);
// Set up the ViewPager and its kin
HelpPagerAdapter adapter = new HelpPagerAdapter(getApplicationContext(), this);
ViewPager helpPager = (ViewPager) findViewById(R.id.helpPager);
helpPager.setAdapter(adapter);
}
public void exitHelp(View view) {
finish();
}
}
Run Code Online (Sandbox Code Playgroud)
这是Activity的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mainHelp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager android:id="@+id/helpPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:text="@string/helpBack"
android:onClick="exitHelp"
style="@style/mainMenuButtons" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
最后,这是错误:
12-08 11:55:23.114: E/AndroidRuntime(9090): FATAL EXCEPTION: main
12-08 11:55:23.114: E/AndroidRuntime(9090): java.lang.OutOfMemoryError
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.graphics.Bitmap.nativeCreate(Native Method)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.graphics.Bitmap.createBitmap(Bitmap.java:605)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.graphics.Bitmap.createBitmap(Bitmap.java:551)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:437)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:618)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:593)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:445)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:775)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.content.res.Resources.loadDrawable(Resources.java:1968)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.content.res.Resources.getDrawable(Resources.java:677)
12-08 11:55:23.114: E/AndroidRuntime(9090): at doop.doop.dedoop.HelpPagerAdapter.instantiateItem(HelpPagerAdapter.java:69)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:801)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.support.v4.view.ViewPager.populate(ViewPager.java:962)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.support.v4.view.ViewPager.populate(ViewPager.java:881)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.support.v4.view.ViewPager$3.run(ViewPager.java:237)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.os.Handler.handleCallback(Handler.java:605)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.os.Handler.dispatchMessage(Handler.java:92)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.os.Looper.loop(Looper.java:137)
12-08 11:55:23.114: E/AndroidRuntime(9090): at android.app.ActivityThread.main(ActivityThread.java:4514)
12-08 11:55:23.114: E/AndroidRuntime(9090): at java.lang.reflect.Method.invokeNative(Native Method)
12-08 11:55:23.114: E/AndroidRuntime(9090): at java.lang.reflect.Method.invoke(Method.java:511)
12-08 11:55:23.114: E/AndroidRuntime(9090): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
12-08 11:55:23.114: E/AndroidRuntime(9090): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
12-08 11:55:23.114: E/AndroidRuntime(9090): at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)
我想可能值得注意的是,这只发生在我正在测试的两个设备中的一个(三星Galaxy SIII,而不是Kindle Fire HD 8.9).
您可以尝试以下几种方法:
保持您在ArrayList中的destroyItem()中从容器中删除的视图.在instantiateItem()期间,首先检查您的arraylist中是否有未使用的视图,如果是,请使用该视图.如果没有,膨胀一个.这样,您只需对3个视图进行充气,然后再循环其余视图.请点击这里获取更多信息有关ViewHolders防止调用findViewById()太多.
使用带有inJustDecodeBounds = true的BitmapFactory.Options来解码位图并检查位图的边界.然后使用inSampleSize解码较小的版本.如果这与您相关请查看此处了解更多信息.
使用pagerAdapter的setPrimaryItem().并在那里加载位图.这样,您只加载当前可见项的位图,从而减少内存负载.但有点打败预加载上一页/下一页的点,以获得更流畅的滚动和更好的用户体验.
示例代码(未测试!)
private ImageView primaryView;
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object)
{
super.setPrimaryItem(container, position, object);
if (this.primaryView == object)
{
//this method might be called a lot, so don't do anything unless the primaryView changes!
return ;
}
if (this.primaryView != null)
{
//recycle the previous bitmap to clear memory
((BitmapDrawable)this.primaryView.getDrawable()).getBitmap().recycle();
}
//set new primary view
this.primaryView = (ImageView) object;
int resourceId = 0;//get image resource id here
//load bitmap here efficiently
this.primaryView.setImageResource(resourceId);
}
Run Code Online (Sandbox Code Playgroud)
helpPager.setOffscreenPageLimit(MAX_PAGES);
Run Code Online (Sandbox Code Playgroud)
当页面超出此范围时它将被破坏。
| 归档时间: |
|
| 查看次数: |
6066 次 |
| 最近记录: |