在另一种方法中使用 SurfaceView addCallback() 而不是在 onCreate() 中使用
use SurfaceView addCallback() in another method instead of using in onCreate()
我想从服务器获取视频的路径,然后使用 surfaceView 播放它们。
如果我用另一个activity class在收到的路径后播放视频就可以了。但我正在尝试使用相同的 activity.
我正在使用 AsyncTask 在后台获取路径。这个 AsyncTask 在 onCreate() 方法中执行。在onPostExecute()中得到路径后,我想在SurfaceView中播放视频
但是 SurfaceView 是在我收到这些路径之前创建的。所以我尝试在onPostExecute()中使用SurfaceView的addCallback()。但是看起来不可能。
我该怎么做?使用 SurfaceView,从服务器获取资源路径后,是否无法在同一 activity 上播放视频?
哦,是的,我找到了解决办法。我会 post 在这里,这样它会对像我这样的人有所帮助。因为我到处都查了解决方案,没有按照这个方法去做。
你的activityclass:
public class PlayActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private SurfaceHolder sh;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//getResource is your AsyncTask
//I will not post it here because it is not the problem we had
getResource _gR = new attemptGetStream(p1, p2);
_gR.execute();
//initiate components
SurfaceView sV = (SurfaceView) findViewById(R.id.main);
assert null != sV : "Surface is null";
sV.getHolder().addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder sHolder) {
//this is the solution.
//only assign holder to a variable but don’t initiate MediaPlayer here
//because we don’t have resource paths yet
//we will initiate MediaPlayer in postExecute method and
//attach to this holder from there
sh = sHolder;
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
log("Surface changed");
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
log("Surface destroyed");
}
//this is our method called from onPostExecute() in our getResource AsyncTask
public void play(String path){
//here initiate the MediaPlayer and assign dataSource
//attach the player to sh(which is our surface holder
try{
MediaPlayer mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDisplay(sh);//sh is the surface holder
mMediaPlayer.setDataSource(getApplicationContext(), path);//path is what we got from onPostExecute method in AsyncTask
mMediaPlayer.prepareAsync();//i use prepareAsync method here so it will not hog the phone
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mP.start();
}
});
}catch (Exception e){//use exception types as you like
e.printStackTrace();
}
}
}
我想从服务器获取视频的路径,然后使用 surfaceView 播放它们。
如果我用另一个activity class在收到的路径后播放视频就可以了。但我正在尝试使用相同的 activity.
我正在使用 AsyncTask 在后台获取路径。这个 AsyncTask 在 onCreate() 方法中执行。在onPostExecute()中得到路径后,我想在SurfaceView中播放视频
但是 SurfaceView 是在我收到这些路径之前创建的。所以我尝试在onPostExecute()中使用SurfaceView的addCallback()。但是看起来不可能。
我该怎么做?使用 SurfaceView,从服务器获取资源路径后,是否无法在同一 activity 上播放视频?
哦,是的,我找到了解决办法。我会 post 在这里,这样它会对像我这样的人有所帮助。因为我到处都查了解决方案,没有按照这个方法去做。
你的activityclass:
public class PlayActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private SurfaceHolder sh;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//getResource is your AsyncTask
//I will not post it here because it is not the problem we had
getResource _gR = new attemptGetStream(p1, p2);
_gR.execute();
//initiate components
SurfaceView sV = (SurfaceView) findViewById(R.id.main);
assert null != sV : "Surface is null";
sV.getHolder().addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder sHolder) {
//this is the solution.
//only assign holder to a variable but don’t initiate MediaPlayer here
//because we don’t have resource paths yet
//we will initiate MediaPlayer in postExecute method and
//attach to this holder from there
sh = sHolder;
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
log("Surface changed");
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
log("Surface destroyed");
}
//this is our method called from onPostExecute() in our getResource AsyncTask
public void play(String path){
//here initiate the MediaPlayer and assign dataSource
//attach the player to sh(which is our surface holder
try{
MediaPlayer mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDisplay(sh);//sh is the surface holder
mMediaPlayer.setDataSource(getApplicationContext(), path);//path is what we got from onPostExecute method in AsyncTask
mMediaPlayer.prepareAsync();//i use prepareAsync method here so it will not hog the phone
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mP.start();
}
});
}catch (Exception e){//use exception types as you like
e.printStackTrace();
}
}
}