ViewPagerIndicator导致随机崩溃

时间:2016-10-26 12:45:11

标签: android xamarin xamarin.android viewpagerindicator

使用ViewPagerIndicator我的应用中的CirclePageIndicator有时会崩溃。这是堆栈跟踪:

System.MethodAccessException: Method `(wrapper dynamic-method) object:dynamic_callback_0 (intptr,intptr)' is inaccessible from method `AnatoliAndroid.Components.CirclePageIndicator/SavedState:InitializeCreator ()'

at com.xxx.anatoli.app.iveMethods:java_interop_jnienv_alloc_object(intptr_intptr&_intptr.args:1337)
at Java.Interop.JniEnvironment+Object.AllocObject(Java.Interop.JniObjectReference_type.args:1337)
at Java.Interop.JniType.AllocObject(.args:1337)
at Java.Interop.JniPeerMembers+JniInstanceMethods.StartCreateInstance(System.String_constructorSignature__System.Type_declaringType__Java.Interop.JniArgumentValue*_parameters.args:1337)
at Android.Views.View+BaseSavedState..ctor(Android.OS.IParcelable_superState.args:1337)
at com.xxx.anatoli.app.AnatoliAndroid.Components.CirclePageIndicator+SavedState..ctor(Android.OS.IParcelable_superState.args:1337)
at com.xxx.anatoli.app.AnatoliAndroid.Components.CirclePageIndicator.OnSaveInstanceState(.args:1337)
at Android.Views.View.n_OnSaveInstanceState(System.IntPtr_jnienv__System.IntPtr_native__this.args:1337)

这是OnCreateView

 public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        var view = inflater.Inflate(Resource.Layout.fragment_home, null);
        var viewPager = view.FindViewById<ViewPager>(Resource.Id.slider_location);
        viewPager.Adapter = new SlideShowAdapter(FragmentManager, new List<string> {
            "http://www.dalih.net/v1/wp-content/uploads/2014/12/wooden-backdrops.jpg",
            "http://www.intrawallpaper.com/static/images/abstract-mosaic-background.png",
            "http://www.intrawallpaper.com/static/images/gradient-background.jpg",
            "http://www.intrawallpaper.com/static/images/518164-backgrounds.jpg"
        });
        CirclePageIndicator indicator = view.FindViewById<CirclePageIndicator>(Resource.Id.indicator);
        indicator.SetViewPager(viewPager);
        int i = 0;
        viewPager.PageSelected += (object sender, ViewPager.PageSelectedEventArgs e) =>
        {
            i = e.Position;
        };

        Task.Factory.StartNew(async () =>
        {
            while (true)
            {
                await Task.Delay(6000);
                Activity.RunOnUiThread(() =>
                {
                    viewPager.SetCurrentItem(i + 1 < viewPager.Adapter.Count ? ++i : i = 0, true);
                });
            }
        });

        return view;
    }

这是适配器:

public class SlideShowAdapter : FragmentPagerAdapter
    {
        List<string> _images;
        public SlideShowAdapter(Android.Support.V4.App.FragmentManager manager, List<string> images) : base(manager)
        {
            _images = images;
        }
        public override int Count
        {
            get
            {
                return _images.Count;
            }
        }

        public override Android.Support.V4.App.Fragment GetItem(int position)
        {
            var fragment = new SliderItemFragment();
            fragment.Arguments = new Bundle();
            fragment.Arguments.PutString("image", _images[position]);
            return fragment;
        }

        public class SliderItemFragment : Android.Support.V4.App.Fragment
        {
            string _image;
            public override void OnCreate(Bundle savedInstanceState)
            {
                base.OnCreate(savedInstanceState);
                if (Arguments != null)
                {
                    _image = Arguments.GetString("image");
                }
            }
            public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
            {
                var view = inflater.Inflate(Resource.Layout.row_slider_item, null);
                var imageView = view.FindViewById<ImageView>(Resource.Id.slider_imageview);
                Picasso.With(Context).Load(_image).Placeholder(Resource.Drawable.profile_toolbar).Into(imageView);
                return view;
            }
        }
    }

在xml中我把CirclePageIndicator和ViewPager放在这样:

 <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <android.support.v4.view.ViewPager
                android:id="@+id/slider_location"
                android:layout_width="match_parent"
                android:layout_height="200dp">
            </android.support.v4.view.ViewPager>
            <AnatoliAndroid.Components.CirclePageIndicator
                android:layout_alignParentBottom="true"
                android:id="@+id/indicator"
                android:padding="10dip"
                android:layout_height="wrap_content"
                android:layout_width="fill_parent"/>
        </RelativeLayout>

对于AnatoliAndroid.Components.CirclePageIndicator,我从ViewPagerIndicator复制并粘贴了exaclty。

1 个答案:

答案 0 :(得分:0)

这个问题看起来像static构造函数:

https://github.com/xamarin/monodroid-samples/blob/fb9d4ed266bdf68bb1f9fa9933130b285712ec82/ViewPagerIndicator/ViewPagerIndicator/Library/CirclePageIndicator.cs#L544

由于没有定义访问修饰符,默认情况下它将设置为private。所以你需要标记它public。 (假设您复制了上面的ViewPagerIndicator示例)

因此以下生成的代码:

  [ExportField("CREATOR")]
  private static CirclePageIndicator.SavedState.SavedStateCreator InitializeCreator()
  {
    return new CirclePageIndicator.SavedState.SavedStateCreator();
  }

如您的错误消息中所述,由于它是私有的,因此无法访问。

看起来大多数其他样本都遵循使用public方法的惯例:

https://github.com/xamarin/monodroid-samples/search?utf8=%E2%9C%93&q=%5BExportField+%28%22CREATOR%22%29%5D&type=Code