In ListView: activity leaked into ServiceConnection <youtube.player.internal>, which was originally associated here

Update:

I just tested my application on another device and found out that I am getting an error on Nexus 4 running Android 4.4.2, but NOT on Desire S running Android 4.0.4. Both of them have the current YouTube app (5.3.32), which is required to use the API.

Question: Why do I receive these ServiceConnectionLeaked messages? (see Logcat section below)

Description:

I use YouTube Android Player 1.0.0 ( https://developers.google.com/youtube/android/player/ ) to upload Thumbnails videos to a ListView with the following adapter code:

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

The snippet containing this View list has the following code:

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

Here's what happens:

  • , YouTube .

(, ):

  • , View, .
  • , .
    • ViewHolder, .
    • ViewHolder , .

, , . ( ):

  • , View, .

( ):

  • , View, .

, -, .

- :

    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, . API- YouTubePlayer Android ( , ).

+4
2

. , , , . , , onCreateView- listView, . afaik, , , ( , ).

. . , . = > .

, YoutubeThumbnail-initializer , . , , YouTubeThumbnails .

+12

, - . , , ServiceConnectionLeaked. .

    android:configChanges="orientation|screenSize"
0

Source: https://habr.com/ru/post/1530856/


All Articles