我有一个包含图片列表和 YouTube 缩略图的 RecyclerView
。如果用户点击 YouTube 缩略图,它会打开一个新 Activity ,在上半部分显示嵌入的 YouTube 视频(使用 YouTube Android Player API
fragment )并在下半部分。
我的问题是,无论我如何尝试实现 YouTube Android Player API
、Android Studio & Leak Canary当我按下后退按钮返回到我的 RecyclerView
时,将始终显示它正在泄漏。我对 LeakCanary
和整个 Android 开发相当陌生。如果我可以提供有关泄漏的更多详细信息,请告诉我,我将编辑这篇文章以包含它。
我已经尝试了很多方法来让它工作,YouTube
建议的两种方式,YouTubePlayerFragment
和 YouTubePlayerView
。在这一点上,我不知道还能做什么。这仅在我使用 YouTube API
时发生,如果我只显示图片,我的 Activity
不会泄漏。非常感谢任何帮助,我已经准备好拔掉头发了。
LeakCanary
YouTubePlayerActivity
是我的类,它不在 YouTube API
中。此外,展开任何 LeakCanary
跟踪都不会泄露任何细节。
回收 View
这是我的 onBindViewHolder()
,我在其中设置了 onClickListener()
,它会打开我的 YouTubePlayerActivity
。
mImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Context context = v.getContext();
Intent youtubeIntent = new Intent(context,YouTubePlayerActivity.class);
Bundle bundle = new Bundle();
bundle.putString("foo", object.getUrl());
bundle.putString("foo1", object.getDescription());
youtubeIntent.putExtras(bundle);
context.startActivity(youtubeIntent, bundle);
}
});
YouTubePlayerActivity.class
显示我的 YouTube 播放器的类的精简版。这是我尝试实现它的许多方法中的最后一种。但是,无论我如何尝试实现它,泄漏都存在。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.detail_main_youtube);
Bundle bundle = getIntent().getExtras();
url = bundle.getString("foo");
description = bundle.getString("foo1");
TextView detailDescription = (TextView) findViewById(R.id.txt_detail_description_youtube);
detailDescription.setText(description);
myFragment = PlayerYouTubeFrag.newInstance("Some random YouTube Id");
myTransaction = getFragmentManager().beginTransaction();
myTransaction.addToBackStack(null);
myTransaction.replace(R.id.youtube_fragment, myFragment).commit();
}
PlayerYouTubeFrag
public class PlayerYouTubeFrag extends YouTubePlayerFragment {
private YouTubePlayer activePlayer;
public static PlayerYouTubeFrag newInstance(String youTubeId) {
PlayerYouTubeFrag playerYouTubeFrag = new PlayerYouTubeFrag();
Bundle bundle = new Bundle();
bundle.putString("youTubeId", youTubeId);
playerYouTubeFrag.setArguments(bundle);
playerYouTubeFrag.init();
return playerYouTubeFrag;
}
private void init() {
initialize(Config.YOUTUBE_API_KEY, new YouTubePlayer.OnInitializedListener() {
@Override
public void onInitializationFailure(YouTubePlayer.Provider arg0, YouTubeInitializationResult arg1) {
}
@Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
activePlayer = player;
activePlayer.setPlayerStyle(YouTubePlayer.PlayerStyle.DEFAULT);
if (!wasRestored) {
activePlayer.loadVideo(getArguments().getString("youTubeId"), 0);
}
}
});
}
}
XML 布局
这是我的 YouTubePlayerActivity
的 xml Frame Layout,它被 Fragment 替换了。
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/detail_main_youtube"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/backgroundColor">
<FrameLayout
android:id="@+id/youtube_fragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:visibility="visible" />
<ScrollView
android:id="@+id/scroll_view_youtube"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<TextView
android:id="@+id/txt_detail_description_youtube"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="20dp"
android:background="@color/backgroundColor"
android:lineSpacingExtra="5dp"
android:textColor="@color/darkTextColor"
android:textSize="15sp" />
</ScrollView>
</LinearLayout>
最佳答案
尝试在您的 PlayerYouTubeFrag
代码中添加这些行:
@Override
public void onDetach() {
super.onDetach();
activePlayer.release();
activePlayer = null;
}
关于使用 RecyclerView 时 Android YouTube API 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42861439/