gpt4 book ai didi

android - 在 ListView : Activity has leaked ServiceConnection 原来绑定(bind)在这里

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:41:07 25 4
gpt4 key购买 nike

更新:

我刚刚在另一台设备上测试了我的应用程序,发现我在运行 Android 4.4.2 的 Nexus 4 上确实遇到了错误,但在运行 Android 4.0.4 的 Desire S 上没有。他们都安装了当前的 YouTube 应用程序 (5.3.32),这是使用 API 所必需的。

问题:为什么我会收到这些 ServiceConnectionLeaked 消息?(请参阅下面的 Logcat)

描述:

我正在使用 YouTube Android Player API 1.0.0 ( https://developers.google.com/youtube/android/player/ ) 通过以下适配器代码在 ListView 中加载视频缩略图:

private final Map<View, YouTubeThumbnailLoader> mThumbnailViewToLoaderMap;

public ListViewAdapter(Activity activity, int layoutId, List<Suggestion> suggestions) {
super(activity, layoutId, suggestions);
mThumbnailViewToLoaderMap = new HashMap<View, YouTubeThumbnailLoader>();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder;

String videoId = getYoutubeId();

// There are three cases here...
if (convertView == null) {
convertView = LayoutInflater.from(mActivity).inflate(R.layout.row_suggestion, parent, false);

holder = new ViewHolder();
holder.thumbnailView = (YouTubeThumbnailView) convertView.findViewById(R.id.youtubeThumbnail);

// ... case 1: The youtube view has not yet been created - we need to initialize the YouTubeThumbnailView.
holder.thumbnailView.setLayoutParams(mThumbnailLayoutParams);
holder.thumbnailView.setTag(videoId);
holder.thumbnailView.initialize(DeveloperKey.DEVELOPER_KEY, this);

convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

// ... case 2 & 3 The view is already created and...
YouTubeThumbnailLoader loader = mThumbnailViewToLoaderMap.get(holder.thumbnailView);

// ... is currently being initialized. We store the current videoId in the tag.
if (loader == null) {
holder.thumbnailView.setTag(videoId);

// ... already initialized. Simply set the right videoId on the loader.
} else {
loader.setVideo(videoId);
}
}

holder.thumbnailView.setImageResource(R.drawable.thumbnail_loading);

return convertView;
}


@Override
public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader youTubeThumbnailLoader) {
String videoId = (String) youTubeThumbnailView.getTag();
mThumbnailViewToLoaderMap.put(youTubeThumbnailView, youTubeThumbnailLoader);
youTubeThumbnailLoader.setOnThumbnailLoadedListener(this);
youTubeThumbnailLoader.setVideo(videoId);
}

public void releaseLoaders() {
for (YouTubeThumbnailLoader loader : mThumbnailViewToLoaderMap.values()) {
loader.release();
}
}

持有此 listView 的 Fragment 具有以下代码:

private ListViewAdapter listViewAdapter;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}

Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = (ViewGroup) inflater.inflate(R.layout.fragment_search_results, container, false);
listView = (ListView) rootView.findViewById(R.id.suggestion_list);

// see if there is already an adapter
// and use it as our adapter (e.g. after device rotation)
if (listViewAdapter != null) {
listView.setAdapter(listViewAdapter);
}

return rootView;
}

@Override
public void onDestroyView() {
super.onDestroyView();
mListViewAdapter.releaseLoaders();
}

这是发生了什么:

  • fragment 已创建,YouTube 缩略图已加载并正确显示。

现在我第一次旋转设备(假设是横向):

  • fragment 已创建,已存在的适配器已连接到 ListView ,但没有为所有当前可见的列表项加载缩略图。
  • 当我向下滚动时,新的列表项进入屏幕。
    • 如果此类新列表项使用新的 ViewHolder,则其缩略图会正确加载。
    • 如果这样的新列表项使用来自第一个可见列表项的 ViewHolder,则根本不会加载其缩略图。

因此这会生成一个缩略图列表,这些缩略图交替正确加载和根本不加载。现在,我将设备旋转第二次(回到纵向):

  • fragment 已创建,现有适配器已连接到 listView,所有缩略图已正确加载。

现在我第三次旋转设备(我们再次处于之前错误的横向):

  • fragment 已创建,现有适配器已连接到 listView,所有缩略图已正确加载。

所以只有在设备第一次旋转后才会发生一些事情,所以可见的缩略图不会加载到它们的列表项中。

第一次轮换后,logcat 会针对每个缩略图请求显示以下消息:

    03-09 17:43:08.770  30446-30446/com.mypackage.name E/ActivityThread: Activity com.mypackage.name.activities.SearchActivity has leaked ServiceConnection com.google.android.youtube.player.internal.r$e@41b0a6c0 that was originally bound here    android.app.ServiceConnectionLeaked: Activity com.mypackage.name.activities.SearchActivity has leaked ServiceConnection com.google.android.youtube.player.internal.r$e@41b0a6c0 that was originally bound here            at android.app.LoadedApk$ServiceDispatcher.(LoadedApk.java:1041)            at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:935)            at android.app.ContextImpl.bindServiceAsUser(ContextImpl.java:1692)            at android.app.ContextImpl.bindService(ContextImpl.java:1680)            at android.content.ContextWrapper.bindService(ContextWrapper.java:496)            at com.google.android.youtube.player.internal.r.e(Unknown Source)            at com.google.android.youtube.player.YouTubeThumbnailView.initialize(Unknown Source)            at com.mypackage.name.adapters.ListViewAdapter.getView(ListViewAdapter.java:94)            at com.mypackage.name.views.ListView.obtainView(ListView.java:1285)            at com.mypackage.name.views.ListView.fillDown(ListView.java:1046)            at com.mypackage.name.views.ListView.populate(ListView.java:720)            at com.mypackage.name.views.ListView.onLayout(ListView.java:677)            at android.view.View.layout(View.java:14520)            at android.view.ViewGroup.layout(ViewGroup.java:4604)            at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1077)            at android.view.View.layout(View.java:14520)            at android.view.ViewGroup.layout(ViewGroup.java:4604)            at android.widget.FrameLayout.onLayout(FrameLayout.java:448)            ...

为什么我会收到这些 ServiceConnectionLeaked 消息?

我已经四处搜索,在大多数情况下,需要进行某种 API 初始化,其中必须提供应用程序上下文而不是 Activity 上下文。但是 YouTubePlayer Android API 没有这样的初始化(至少在我的代码部分没有)。

最佳答案

我终于找到了解决方案。我跟踪了第一次创建所有 vie 和 fragment 时发生的每一个步骤,并将其与第一次轮换期间发生的情况进行了比较。记下创建和重新使用的每个对象,我发现在 fragment 的 onCreateView-Method 期间我重新启动了 listView,但将旧适配器设置为它。到目前为止,这不是问题,也是 afaik 的良好做法,因为我可以重新使用适配器持有的所有信息(如果我错了,请纠正我)。

问题存在于早期的适配器初始化中。适配器在第一次旋转之前初始化,并将当前 Activity 作为其上下文。因此,在旋转之后,它仍然具有旧的纵向 Activity 作为上下文,尽管它位于新创建的横向 Activity 中。 => 经典 Activity 泄漏。

YoutubeThumbnail-initializer 似乎使用了这个上下文,尽管没有关于此的提示或文档。因此,当我使用应用程序上下文初始化适配器时,此应用程序上下文用于 YouTubeThumbnails,不会产生泄漏。

关于android - 在 ListView : Activity has leaked ServiceConnection <youtube. player.internal> 原来绑定(bind)在这里,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22285129/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com