1

我正在尝试将 viewpager 与媒体播放器一起使用,但遇到了一些问题。我的应用程序设置在您单击 gridview 中的视频的位置,然后当屏幕变得可见时,它将开始播放视频。当我第一次打开视频时,它播放得很好。viewpager 适用于向左或向右的两个页面。但是,当我检查该应用程序时,它会冻结并崩溃。

我设置了一些日志,并在我的 pageradapater 类中发现,在调用 setPrimaryItem 之后,当我调用时有一个 IllegalArgumentExceptionMediaplayer.setdisplay(holder) 表示The surface has been relased我已经尝试进行一些研究和测试,但我找不到表面正在释放的位置. 出现此错误对我来说似乎很奇怪,但视频仍在播放。我不确定为什么会这样。

我最好的猜测是 pageradapater 在开始时设置了 Viewgroup 中的所有页面这可能会导致某种问题,因为表面被设置在 ViewGroup 中的其他位置。

我正在寻求一些帮助。我的代码如下

FullImageActivity.java

public class FullImageActivity extends Activity {


private static final String TAG = "MediaPlayer shit";
//MediaPlayer player;
//SurfaceView surfaceview;
SurfaceHolder surfaceHolder;
Gridview gridview = new Gridview();
int width;
int height;
Cursor cursor;
DisplayImageOptions options;
ViewPager viewpager;
TheViewPager theviewpager;
String path;
int position;
String[] projection = { GridviewData.ROWID, GridviewData.BITMAPPATH, GridviewData.VIDEOFILEPATH};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.image_pager);

    Intent i = getIntent();

    position = i.getExtras().getInt("position");
    path = i.getExtras().getString("videopath");


    cursor = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, 
                                gridview.mediaColumns, 
                                MediaStore.Video.Media.DATA + " like ?", 
                                new String[] {Environment.getExternalStorageDirectory().getPath() + "/Reelcam/TheReelcams/%"}, 
                                null); 

    theviewpager = new  TheViewPager(cursor, this);
    viewpager = (ViewPager) findViewById(R.id.pager);
    viewpager.setOffscreenPageLimit(2);
    viewpager.setAdapter(theviewpager);

}


@Override
protected void onPause() {
    //surfaceview.setVisibility(View.GONE);

    if ( theviewpager.player != null ) 
    {
        if ( theviewpager.player.isPlaying() )
            theviewpager.player.stop();
        theviewpager.player.release();
        theviewpager.player = null;
    }
    super.onPause();
}
@Override
protected void onResume() {
    //surfaceview.setVisibility(View.VISIBLE);
    viewpager.setCurrentItem(position);
    super.onResume();
}


@Override
protected void onDestroy() {
    cursor.close();
    super.onDestroy();
}

 }

ViewPager.java

public class TheViewPager extends PagerAdapter implements OnCompletionListener, Callback, OnPreparedListener  {

private static final String TAG = "MediaPlayer shit";
LayoutInflater inflater;
MediaPlayer player;
String vpath;

Cursor cursor;
Activity activity;
LayoutInflater layoutInflater;
boolean hasActiveHolder = false;
FullImageActivity fullimage;
public TheViewPager(Cursor cursor2, Activity activity) {
    this.cursor = cursor2;
    layoutInflater = activity.getLayoutInflater();
    this.activity = activity;
    this.fullimage = new FullImageActivity();


}

@Override
public int getCount() {
    return cursor.getCount();
}

@Override
public void finishUpdate(ViewGroup container) {
    super.finishUpdate(container);
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {

    container.removeView((View) object);
}

@Override
public Object instantiateItem(ViewGroup view, int position) {

    View v = layoutInflater.inflate(R.layout.full_image, null, false);

    SurfaceView surfaceview = (SurfaceView)v.findViewById(R.id.surfaceview);



    SurfaceHolder holder = surfaceview.getHolder();
    v.setTag(holder);
    ((ViewPager) view).addView(v, 0);
    return v;

}

@Override
public boolean isViewFromObject(View view, Object object) {
    return view.equals(((View) object));
}

@Override
public void setPrimaryItem(ViewGroup container, int position,
        Object object) {
    Log.i(TAG, "setPrimaryItem");
    View view = (View) object;


    cursor.moveToPosition(position);
    vpath = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA));


    SurfaceHolder holder = (SurfaceHolder) view.getTag();
    player = new MediaPlayer();
    try {
        player.reset();
        player.setDataSource(vpath);            
        player.setOnCompletionListener(this);
        player.setOnPreparedListener(this);

        player.setDisplay(holder);
        player.prepare();

    }   
     catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (SecurityException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }


    super.setPrimaryItem(container, position, object);
}

@Override
public void onCompletion(MediaPlayer player) {
    Log.i(TAG, "onCompleiton");

    if (player != null){
        if ( player.isPlaying() )
            player.stop();
    player.reset();
    player.release();
    player = null;
    }
}
@Override
public void startUpdate(ViewGroup container) {
    super.startUpdate(container);
}



@Override
public void onPrepared(MediaPlayer arg0) {
    arg0.start();

}

作为旁注,这是我的逻辑:

我正在使用 instantiateItem 方法来设置视图。Android 文档说将会Create the page for the given position,所以我假设我将在这里设置视图,稍后将填充到 setPrimaryItem 中。setPrimaryItem 方法的文档说Called to inform the adapter of which item is currently considered to be the "primary", that is the one show to the user as the current page.因为这个我想在这里设置媒体播放器,因为它是唯一可以查看视频的地方。我想我可能会遗漏一些东西。

4

1 回答 1

2

ViewPagers,默认只保留与当前页面直接相邻的页面(即当前页面左侧的页面、当前页面以及当前页面右侧的页面)。因此,如果您距离视频播放页面两页,它将被分离并且不再处于活动状态。您可以通过ViewPager.setOffscreenPageLimit将内存中保留的页面数更改为高于默认值的1. 请注意,这确实会增加所需的内存量,并且不应该太高 - 请务必在内存量较低的设备上进行测试。

于 2013-07-11T19:01:58.383 回答