65

我们已经使用了适用于 android 的 YouTube API,但是在使用 YouTube 播放器和 YouTube 播放器视图快速关闭和打开相同的活动时存在问题。此问题也出现在示例应用程序中,当我尝试打开Fullscreen活动(不单击fullscreenbutton)然后使用后退按钮关闭活动并一次又一次地关闭活动时。

YouTube 应用程序崩溃如下:

10-11 15:14:53.313: E/ActivityThread(22537): Activity com.example.myvideo.FullscreenDemoActivity 已泄露 ServiceConnection com.google.android.youtube.player.internal.r$e@46095818 最初绑定在这里

我试图覆盖OnStop以释放播放器,但没有积极的结果。请有人帮忙!

Fullscreen活动修改 - 原始和这个之间的几行区别:

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();
    }
}
4

2 回答 2

1

您可以执行以下步骤以确保解决内存泄漏问题:

  • 使用应用程序上下文
    • 例如,创建一个名为YoutubeMyAPIwhich implements的类YouTubePlayer.OnFullscreenListener
    • YoutubeMyAPIApplicationClass中创建它的实例
  • 无论您在哪里通过获取onInitializedListener传递实例YoutubeMyAPI((MyApp)getApplicationContext()).instanceOfYoutubeMyAPI

希望你有一个实现这个的总体思路,显然这只是一种解决方法,有更好的方法来做到这一点......

于 2021-08-16T08:22:04.323 回答
0

我知道这不是您问题的正确答案,但大约 10 个月前,我自己在 YoutubeAPI 上苦苦挣扎。我真的很想使用来自 google 的 propper YoutubeAPI,因为那是官方 API 并且因为未来的支持,它是在内部制作的等等。
在面对你自己的许多挑战后,我终于给了另一个第三方图书馆一个机会,它是白天和黑夜

com.pierfrancescosoffritti.androidyoutubeplayer这是 pier francesco soffritti 的依赖名称如果您继续面临挑战,我强烈建议您尝试一下。当我尝试使用 YoutubeAPI 时,它已经有好几年没有得到维护了,我阅读并亲自面对到处的错误。

这里有一篇由这个人自己写的关于为什么第三方图书馆是这里的路的文章。

于 2021-10-10T01:18:44.720 回答