diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java
index 82ec610be7..18bf9eeb8c 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayer.java
@@ -15,6 +15,8 @@
*/
package com.google.android.exoplayer2;
+import android.os.Looper;
+import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.audio.MediaCodecAudioRenderer;
import com.google.android.exoplayer2.metadata.MetadataRenderer;
@@ -88,7 +90,9 @@ import com.google.android.exoplayer2.video.MediaCodecVideoRenderer;
* thread. The application's main thread is ideal. Accessing an instance from multiple threads is
* discouraged, however if an application does wish to do this then it may do so provided that it
* ensures accesses are synchronized.
- *
Registered listeners are called on the thread that created the ExoPlayer instance.
+ * Registered listeners are called on the thread that created the ExoPlayer instance, unless
+ * the thread that created the ExoPlayer instance does not have a {@link Looper}. In that case,
+ * registered listeners will be called on the application's main thread.
* An internal playback thread is responsible for playback. Injected player components such as
* Renderers, MediaSources, TrackSelectors and LoadControls are called by the player on this
* thread.
@@ -253,7 +257,8 @@ public interface ExoPlayer {
/**
* Register a listener to receive events from the player. The listener's methods will be called on
- * the thread that was used to construct the player.
+ * the thread that was used to construct the player. However, if the thread used to construct the
+ * player does not have a {@link Looper}, then the listener will be called on the main thread.
*
* @param listener The listener to register.
*/
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerFactory.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerFactory.java
index 7aecd20d4e..97a310c3da 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerFactory.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerFactory.java
@@ -16,7 +16,6 @@
package com.google.android.exoplayer2;
import android.content.Context;
-import android.os.Looper;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
import com.google.android.exoplayer2.trackselection.TrackSelector;
@@ -29,8 +28,7 @@ public final class ExoPlayerFactory {
private ExoPlayerFactory() {}
/**
- * Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
- * {@link Looper}.
+ * Creates a {@link SimpleExoPlayer} instance.
*
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
@@ -45,8 +43,7 @@ public final class ExoPlayerFactory {
}
/**
- * Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
- * {@link Looper}. Available extension renderers are not used.
+ * Creates a {@link SimpleExoPlayer} instance. Available extension renderers are not used.
*
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
@@ -63,8 +60,7 @@ public final class ExoPlayerFactory {
}
/**
- * Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
- * {@link Looper}.
+ * Creates a {@link SimpleExoPlayer} instance.
*
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
@@ -86,8 +82,7 @@ public final class ExoPlayerFactory {
}
/**
- * Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
- * {@link Looper}.
+ * Creates a {@link SimpleExoPlayer} instance.
*
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
@@ -112,8 +107,7 @@ public final class ExoPlayerFactory {
}
/**
- * Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
- * {@link Looper}.
+ * Creates a {@link SimpleExoPlayer} instance.
*
* @param context A {@link Context}.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
@@ -123,8 +117,7 @@ public final class ExoPlayerFactory {
}
/**
- * Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
- * {@link Looper}.
+ * Creates a {@link SimpleExoPlayer} instance.
*
* @param renderersFactory A factory for creating {@link Renderer}s to be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
@@ -135,8 +128,7 @@ public final class ExoPlayerFactory {
}
/**
- * Creates a {@link SimpleExoPlayer} instance. Must be called from a thread that has an associated
- * {@link Looper}.
+ * Creates a {@link SimpleExoPlayer} instance.
*
* @param renderersFactory A factory for creating {@link Renderer}s to be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
@@ -148,8 +140,7 @@ public final class ExoPlayerFactory {
}
/**
- * Creates an {@link ExoPlayer} instance. Must be called from a thread that has an associated
- * {@link Looper}.
+ * Creates an {@link ExoPlayer} instance.
*
* @param renderers The {@link Renderer}s that will be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
@@ -159,8 +150,7 @@ public final class ExoPlayerFactory {
}
/**
- * Creates an {@link ExoPlayer} instance. Must be called from a thread that has an associated
- * {@link Looper}.
+ * Creates an {@link ExoPlayer} instance.
*
* @param renderers The {@link Renderer}s that will be used by the instance.
* @param trackSelector The {@link TrackSelector} that will be used by the instance.
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java
index 4131b97954..cb0958a3b1 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java
@@ -92,7 +92,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
trackGroups = TrackGroupArray.EMPTY;
trackSelections = emptyTrackSelections;
playbackParameters = PlaybackParameters.DEFAULT;
- eventHandler = new Handler() {
+ Looper eventLooper = Looper.myLooper() != null ? Looper.myLooper() : Looper.getMainLooper();
+ eventHandler = new Handler(eventLooper) {
@Override
public void handleMessage(Message msg) {
ExoPlayerImpl.this.handleEvent(msg);
diff --git a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java
index 28ba8cf9d7..6094513913 100644
--- a/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java
+++ b/library/core/src/main/java/com/google/android/exoplayer2/SimpleExoPlayer.java
@@ -20,6 +20,7 @@ import android.graphics.SurfaceTexture;
import android.media.MediaCodec;
import android.media.PlaybackParams;
import android.os.Handler;
+import android.os.Looper;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.Surface;
@@ -111,8 +112,10 @@ public class SimpleExoPlayer implements ExoPlayer {
protected SimpleExoPlayer(RenderersFactory renderersFactory, TrackSelector trackSelector,
LoadControl loadControl) {
componentListener = new ComponentListener();
- renderers = renderersFactory.createRenderers(new Handler(), componentListener,
- componentListener, componentListener, componentListener);
+ Looper eventLooper = Looper.myLooper() != null ? Looper.myLooper() : Looper.getMainLooper();
+ Handler eventHandler = new Handler(eventLooper);
+ renderers = renderersFactory.createRenderers(eventHandler, componentListener, componentListener,
+ componentListener, componentListener);
// Obtain counts of video and audio renderers.
int videoRendererCount = 0;