Android Youtube Player API activity finish and create
AndroidAndroid ActivityYoutubeYoutube ApiAndroid AppcompatAndroid Problem Overview
We have used the YouTube API for android, but there is a problem with a fast closing and opening the same activity with the YouTube player and the YouTube player view. This problem appears in the sample application also, when I try to open Fullscreen
activity (without clicking fullscreenbutton
) then close activity with the back button and again and again.
YouTube app is crashing like : >10-11 15:14:53.313: E/ActivityThread(22537): Activity com.example.myvideo.FullscreenDemoActivity has leaked ServiceConnection com.google.android.youtube.player.internal.r$e@46095818 that was originally bound here
I have tried to override OnStop
to release the player but with no positive result. Please somebody help!
Fullscreen
activity modification - a few lines difference between original and this one :
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayer.PlayerStyle;
import com.google.android.youtube.player.YouTubePlayerView;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
/**
* Sample activity showing how to properly enable custom fullscreen behavior.
* <p>
* This is the preferred way of handling fullscreen because of the default fullscreen implementation
* will cause re-buffering of the video.
*/
public class FullscreenDemoActivity extends YouTubeFailureRecoveryActivity implements
View.OnClickListener,
CompoundButton.OnCheckedChangeListener,
YouTubePlayer.OnFullscreenListener {
private static final int PORTRAIT_ORIENTATION = Build.VERSION.SDK_INT < 9
? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
: ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
private LinearLayout baseLayout;
private YouTubePlayerView playerView;
private YouTubePlayer player;
private Button fullscreenButton;
private CompoundButton checkbox;
private View otherViews;
public boolean CanClose = false;
private boolean fullscreen;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.fullscreen_demo);
baseLayout = (LinearLayout) findViewById(R.id.layout);
playerView = (YouTubePlayerView) findViewById(R.id.player);
fullscreenButton = (Button) findViewById(R.id.fullscreen_button);
checkbox = (CompoundButton) findViewById(R.id.landscape_fullscreen_checkbox);
otherViews = findViewById(R.id.other_views);
checkbox.setOnCheckedChangeListener(this);
// You can use your own button to switch to fullscreen too
fullscreenButton.setOnClickListener(this);
playerView.initialize(DeveloperKey.DEVELOPER_KEY, this);
doLayout();
} catch (Exception e) { }
}
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
try {
this.player = player;
player.setPlayerStyle(PlayerStyle.MINIMAL);
//player.setShowFullscreenButton(true);
setControlsEnabled();
// Specify that we want to handle fullscreen behavior ourselves.
player.addFullscreenControlFlag(YouTubePlayer.FULLSCREEN_FLAG_CUSTOM_LAYOUT);
player.setOnFullscreenListener(this);
if (!wasRestored) {
player.cueVideo(MainActivity.CurrentVideo);
}
} catch (Exception e) { }
}
@Override
protected YouTubePlayer.Provider getYouTubePlayerProvider() {
return playerView;
}
@Override
public void onClick(View v) {
player.setFullscreen(!fullscreen);
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
try {
int controlFlags = player.getFullscreenControlFlags();
if (isChecked) {
// If you use the FULLSCREEN_FLAG_ALWAYS_FULLSCREEN_IN_LANDSCAPE, your activity's normal UI
// should never be laid out in landscape mode (since the video will be fullscreen whenever the
// activity is in landscape orientation). Therefore you should set the activity's requested
// orientation to portrait. Typically you would do this in your AndroidManifest.xml, we do it
// programmatically here since this activity demos fullscreen behavior both with and without
// this flag).
setRequestedOrientation(PORTRAIT_ORIENTATION);
controlFlags |= YouTubePlayer.FULLSCREEN_FLAG_ALWAYS_FULLSCREEN_IN_LANDSCAPE;
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
controlFlags &= ~YouTubePlayer.FULLSCREEN_FLAG_ALWAYS_FULLSCREEN_IN_LANDSCAPE;
}
player.setFullscreenControlFlags(controlFlags);
} catch (Exception e) { }
}
private void doLayout() {
try {
LinearLayout.LayoutParams playerParams = (LinearLayout.LayoutParams) playerView.getLayoutParams();
if (fullscreen) {
// When in fullscreen, the visibility of all other views than the player should be set to
// GONE and the player should be laid out across the whole screen.
playerParams.width = LayoutParams.MATCH_PARENT;
playerParams.height = LayoutParams.MATCH_PARENT;
otherViews.setVisibility(View.GONE);
} else {
// This layout is up to you - this is just a simple example (vertically stacked boxes in
// portrait, horizontally stacked in landscape).
otherViews.setVisibility(View.VISIBLE);
ViewGroup.LayoutParams otherViewsParams = otherViews.getLayoutParams();
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
playerParams.width = otherViewsParams.width = 0;
playerParams.height = WRAP_CONTENT;
otherViewsParams.height = MATCH_PARENT;
playerParams.weight = 1;
baseLayout.setOrientation(LinearLayout.HORIZONTAL);
} else {
playerParams.width = otherViewsParams.width = MATCH_PARENT;
playerParams.height = WRAP_CONTENT;
playerParams.weight = 0;
otherViewsParams.height = 0;
baseLayout.setOrientation(LinearLayout.VERTICAL);
}
setControlsEnabled();
}
} catch (Exception e) { }
}
private void setControlsEnabled() {
checkbox.setEnabled(player != null &&
getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
fullscreenButton.setEnabled(player != null);
}
@Override
public void onFullscreen(boolean isFullscreen) {
fullscreen = isFullscreen;
doLayout();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
doLayout();
}
@Override
public void onStop() {
if (player != null) {
player.release();
player = null;
}
super.onStop();
}
@Override
public void finish() {
Intent data = new Intent();
setResult(RESULT_OK, data);
super.finish();
}
}
Android Solutions
Solution 1 - Android
You can do following steps to ensure memory leak problem to get resolved:
- Use Application Context
-
- Create a class for example named
YoutubeMyAPI
which implementsYouTubePlayer.OnFullscreenListener
- Create a class for example named
-
- create instance of that
YoutubeMyAPI
inApplication
Class
- create instance of that
- Wherever you are passing
onInitializedListener
pass instance ofYoutubeMyAPI
by getting((MyApp)getApplicationContext()).instanceOfYoutubeMyAPI
Hopefully you got the general idea to implement this obviously this is just a workaround there are better ways to do this...
Solution 2 - Android
I know this is not a proper answer to your question, but around 10 months ago, I struggled with the YouTube API myself. I really wanted to use the proper YouTube API from Google because that's the official API. Because of future support, it being made inhouse, and so on.
After facing many challenges such as your own, I finally gave another third-party library a chance and it was night and day
com.pierfrancescosoffritti.androidyoutubeplayer
this is the name of the dependency by Pier Francesco Soffritti and if you continue facing challenges, I seriously recommend you give it a try. When I tried using the YouTube API it hadn't been maintained for several years and I read about and personally faced bugs everywhere.
Here an article written by the man himself about why a third-party library is the way to go here.