我有一个由Fragment列表动态填充的ViewPager,所有这些Fragment都有一个由多种类型的元素组成的RecyclerView (每个ItemView彼此不同,没有办法知道哪种类型的视图位于哪个位置)。为了填充这个RecyclerView,我们使用了多个相应类型的ViewHolders。其中一个是YoutubeHolder,它应该打开一个YoutubeStandalonePlayer实例。这就是我的问题:每当方向改变或在包含YoutubeHolder的Fragment上按下back按钮时,我就会得到一个异常,显示为DetailActivity has leaked ServiceConnection com.google.android.youtube.player.internal.r$e@1ece5fa2 that was originally bound here。如果我在Fragment之间滑动,也会发生这种情况。现在,我并不是不释放在onInitializationSuccess调用中获得的YoutubeThumbnailLoader。我在StackOverflow上读到了很多关于这方面的问题,但似乎没有任何问题对我有帮助!
下面是我的YoutubeHolder的代码
public class ElementYoutubeHolder extends BaseElementHolder implements YouTubeThumbnailView.OnInitializedListener {
YouTubeThumbnailView thumbView;
YouTubeThumbnailLoader thumbLoader;
String youTubeKey = null;
String videoId;
public ElementYoutubeHolder(View itemView) {
super(itemView);
}
@Override
public void bind(final StoryElement element) {
if (element.url() == null) {
return;
}
Uri uri = Uri.parse(element.url());
videoId = uri.getQueryParameter("v");
thumbView.setTag(videoId);
thumbView.initialize(youTubeKey, this);
thumbView.setImageResource(R.drawable.placeholder);
itemView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View view) {
}
@Override
public void onViewDetachedFromWindow(View view) {
itemView.removeOnAttachStateChangeListener(this);
if (thumbLoader != null) {
try {
thumbLoader.setOnThumbnailLoadedListener(null);
thumbLoader.release();
Log.v(ElementYoutubeHolder.class.getSimpleName(), "thumbLoader released");
} catch (IllegalStateException ile) {
//May be this youtube thumbnail loader already is released, so catch the exception here
}
}
}
});
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = YouTubeStandalonePlayer.createVideoIntent((Activity) view.getContext(), youTubeKey, videoId);
view.getContext().startActivity(intent);
}
});
}
@Override
public View getView() {
return itemView;
}
@Override
public boolean recreate() {
return true;
}
/**
* Static method to get YoutubeHolder
*
* @param parent {@link ViewGroup}
* @return {@link ElementYoutubeHolder}
*/
public static ElementYoutubeHolder create(ViewGroup parent) {
Log.v(ElementYoutubeHolder.class.getSimpleName(), "created element youtube holder");
View view = ViewUtils.inflate(R.layout.qs_story_layout_youtube, parent);
ElementYoutubeHolder holder = new ElementYoutubeHolder(view);
holder.thumbView = (YouTubeThumbnailView) view.findViewById(R.id.qs_youtube_thumbnail);
holder.youTubeKey = parent.getContext().getString(R.string.qs_youtube_key);
return holder;
}
@Override
public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader youTubeThumbnailLoader) {
Log.v(ElementYoutubeHolder.class.getSimpleName(), "initialization success");
String videoId = (String) youTubeThumbnailView.getTag();
youTubeThumbnailLoader.setVideo(videoId);
thumbLoader = youTubeThumbnailLoader;
}
@Override
public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {
Log.v(ElementYoutubeHolder.class.getSimpleName(), "initialization failure: " + youTubeInitializationResult.toString());
thumbLoader = null;
}
public void recycleYoutubeThumbnailLoader() {
if (thumbLoader != null) {
thumbLoader.release();
}
}
}我还从适配器调用recycleYoutubeThumbnailLoader(),如下所示:
@Override
public void onViewDetachedFromWindow(BaseElementHolder holder) {
if(holder instanceof ElementYoutubeHolder){
((ElementYoutubeHolder) holder).recycleYoutubeThumbnailLoader();
Log.v(StoryAdapter.class.getSimpleName(), "thumnailLoader recycled");
}
super.onViewDetachedFromWindow(holder);
}还有一件事:这个错误并没有使我的应用崩溃。我的应用程序运行正常。只有这个错误才会出现在LogCat上,我想修复它,因为它可能会在以后导致更大的问题。
下面是堆栈跟踪:
06-14 19:44:49.345 4688-4688/com.example.sampleapp E/ActivityThread: Activity com.example.sampleapp.DetailActivity has leaked ServiceConnection com.google.android.youtube.player.internal.r$e@1ece5fa2 that was originally bound here
android.app.ServiceConnectionLeaked: Activity com.example.sampleapp.DetailActivity has leaked ServiceConnection com.google.android.youtube.player.internal.r$e@1ece5fa2 that was originally bound here
at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:1083)
at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:977)
at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1794)
at android.app.ContextImpl.bindService(ContextImpl.java:1777)
at android.content.ContextWrapper.bindService(ContextWrapper.java:539)
at com.google.android.youtube.player.internal.r.e(Unknown Source)
at com.google.android.youtube.player.YouTubeThumbnailView.initialize(Unknown Source)
at com.example.sampleapp.viewholders.ElementYoutubeHolder.bind(ElementYoutubeHolder.java:42)
at com.quintype.coreui.story.StoryPresenter.bind(StoryPresenter.java:281)
at com.example.sampleapp.adapters.StoryAdapter.onBindViewHolder(StoryAdapter.java:77)
at com.example.sampleapp.adapters.StoryAdapter.onBindViewHolder(StoryAdapter.java:40)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5471)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5504)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4741)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4617)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1994)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1390)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1353)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:574)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3028)
at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:2625)
at android.view.View.measure(View.java:17637)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
at android.view.View.measure(View.java:17637)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1560)
at android.view.View.measure(View.java:17637)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536)
at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:668)
at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:735)
at android.view.View.measure(View.java:17637)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
at android.view.View.measure(View.java:17637)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17637)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
at android.view.View.measure(View.java:17637)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17637)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536)
at android.widget.FrameLayout.onMeasure(Fra发布于 2016-06-14 23:02:57
您有一些服务,并调用某个地方的bindService。因此,您只需调用unbindService
这是Context方法之一。如果你打开了connection,你需要在onDestroy方法中关闭它(或者当你不需要它的时候)。
https://stackoverflow.com/questions/37814851
复制相似问题