下面列出了怎么用android.support.annotation.MainThread的API类实例代码及写法,或者点击链接到github查看源代码。
@MainThread
public static void startActivityForResult(@NonNull final Activity activity, @NonNull final LifecycleOwner lifecycleOwner,
@NonNull final Intent intent, final int requestCode,
@NonNull final ActivityResultCallback resultCallback) {
ThreadUtility.checkUIThread();
if (isDestroyed(activity, lifecycleOwner)) {
return;
}
final SceneActivityCompatibilityLayerFragment fragment = install(activity);
if (fragment.isAdded()) {
fragment.startActivityForResultByScene(lifecycleOwner, intent, requestCode, resultCallback);
} else {
fragment.addOnActivityCreatedCallback(new SceneActivityCompatibilityLayerFragment.OnActivityCreatedCallback() {
@Override
public void onActivityCreated() {
fragment.removeOnActivityCreatedCallback(this);
if (isDestroyed(activity, lifecycleOwner)) {
return;
}
fragment.startActivityForResultByScene(lifecycleOwner, intent, requestCode, resultCallback);
}
});
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@MainThread
public static void startActivityForResult(@NonNull final Activity activity, @NonNull final LifecycleOwner lifecycleOwner,
@NonNull final Intent intent, final int requestCode,
@Nullable final Bundle options,
@NonNull final ActivityResultCallback resultCallback) {
ThreadUtility.checkUIThread();
if (isDestroyed(activity, lifecycleOwner)) {
return;
}
final SceneActivityCompatibilityLayerFragment fragment = install(activity);
if (fragment.isAdded()) {
fragment.startActivityForResultByScene(lifecycleOwner, intent, requestCode, options, resultCallback);
} else {
fragment.addOnActivityCreatedCallback(new SceneActivityCompatibilityLayerFragment.OnActivityCreatedCallback() {
@Override
public void onActivityCreated() {
fragment.removeOnActivityCreatedCallback(this);
if (isDestroyed(activity, lifecycleOwner)) {
return;
}
fragment.startActivityForResultByScene(lifecycleOwner, intent, requestCode, options, resultCallback);
}
});
}
}
@MainThread
@RequiresApi(Build.VERSION_CODES.M)
public static void requestPermissions(@NonNull final Activity activity, @NonNull final LifecycleOwner lifecycleOwner,
@NonNull final String[] permissions, final int requestCode,
@NonNull final PermissionResultCallback resultCallback) {
ThreadUtility.checkUIThread();
if (isDestroyed(activity, lifecycleOwner)) {
return;
}
final SceneActivityCompatibilityLayerFragment fragment = install(activity);
if (fragment.isAdded()) {
fragment.requestPermissionsByScene(lifecycleOwner, permissions, requestCode, resultCallback);
} else {
fragment.addOnActivityCreatedCallback(new SceneActivityCompatibilityLayerFragment.OnActivityCreatedCallback() {
@Override
public void onActivityCreated() {
fragment.removeOnActivityCreatedCallback(this);
if (isDestroyed(activity, lifecycleOwner)) {
return;
}
fragment.requestPermissionsByScene(lifecycleOwner, permissions, requestCode, resultCallback);
}
});
}
}
@MainThread
public static void addConfigurationChangedListener(@NonNull final Activity activity, @NonNull final LifecycleOwner lifecycleOwner,
@NonNull final ConfigurationChangedListener configurationChangedListener) {
ThreadUtility.checkUIThread();
if (isDestroyed(activity, lifecycleOwner)) {
return;
}
final SceneActivityCompatibilityLayerFragment fragment = install(activity);
if (fragment.isAdded()) {
fragment.addConfigurationChangedListener(lifecycleOwner, configurationChangedListener);
} else {
fragment.addOnActivityCreatedCallback(new SceneActivityCompatibilityLayerFragment.OnActivityCreatedCallback() {
@Override
public void onActivityCreated() {
fragment.removeOnActivityCreatedCallback(this);
if (isDestroyed(activity, lifecycleOwner)) {
return;
}
fragment.addConfigurationChangedListener(lifecycleOwner, configurationChangedListener);
}
});
}
}
@MainThread
public void observe(LifecycleOwner owner, final Observer<T> observer) {
if (hasActiveObservers()) {
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.");
}
// Observe the internal MutableLiveData
super.observe(owner, new Observer<T>() {
@Override
public void onChanged(@Nullable T t) {
if (mPending.compareAndSet(true, false)) {
observer.onChanged(t);
}
}
});
}
@MainThread
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull final Observer<T> observer) {
if (single) {
if (hasActiveObservers()) {
L.d("Multiple observers registered but only one will be notified of changes.");
}
// Observe the internal MutableLiveData
super.observe(owner, new Observer<T>() {
@Override
public void onChanged(@Nullable T t) {
if (mPending.compareAndSet(true, false)) {
observer.onChanged(t);
}
}
});
} else {
super.observe(owner, observer);
}
}
/**
* Browse to the specified media.
*
* @param media Can be a media returned by MediaBrowser.
* @param flags see {@link Flag}
*/
@MainThread
public void browse(Media media, int flags) {
/* media can be associated with a medialist,
* so increment ref count in order to don't clean it with the medialist
*/
media.retain();
media.addOption(IGNORE_LIST_OPTION + mIgnoreList);
if ((flags & Flag.NoSlavesAutodetect) != 0)
media.addOption(":no-sub-autodetect-file");
if ((flags & Flag.ShowHiddenFiles) != 0)
media.addOption(":show-hiddenfiles");
int mediaFlags = Media.Parse.ParseNetwork;
if ((flags & Flag.Interact) != 0)
mediaFlags |= Media.Parse.DoInteract;
reset();
mBrowserMediaList = media.subItems();
mBrowserMediaList.setEventListener(mBrowserMediaListEventListener, mHandler);
media.parseAsync(mediaFlags, 0);
mMedia = media;
}
@MainThread
public void observeSticky(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
@MainThread
private void broadcastInternal(T value, boolean foreground, boolean onlyInApp) {
logger.log(Level.INFO, "broadcast: " + value + " foreground: " + foreground +
" with key: " + key);
Application application = AppUtils.getApp();
if (application == null) {
logger.log(Level.WARNING, "application is null, you can try setContext() when config");
return;
}
Intent intent = new Intent(IpcConst.ACTION);
if (foreground && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
}
if (onlyInApp) {
intent.setPackage(application.getPackageName());
}
intent.putExtra(IpcConst.KEY, key);
boolean handle = ProcessorManager.getManager().writeTo(intent, value);
try {
if (handle) {
application.sendBroadcast(intent);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
@MainThread
public void attachViews(OnNewVideoLayoutListener onNewVideoLayoutListener) {
if (mSurfacesState.get() != SURFACE_STATE_INIT || mSurfaceHelpers[ID_VIDEO] == null)
throw new IllegalStateException("already attached or video view not configured");
mSurfacesState.set(SURFACE_STATE_ATTACHED);
synchronized (mNativeLock) {
mOnNewVideoLayoutListener = onNewVideoLayoutListener;
mNativeLock.buffersGeometryConfigured = false;
mNativeLock.buffersGeometryAbort = false;
}
for (int id = 0; id < ID_MAX; ++id) {
final SurfaceHelper surfaceHelper = mSurfaceHelpers[id];
if (surfaceHelper != null)
surfaceHelper.attach();
}
}
@Override
@MainThread
public void detachViews() {
if (mSurfacesState.get() == SURFACE_STATE_INIT)
return;
mSurfacesState.set(SURFACE_STATE_INIT);
mHandler.removeCallbacksAndMessages(null);
synchronized (mNativeLock) {
mOnNewVideoLayoutListener = null;
mNativeLock.buffersGeometryAbort = true;
mNativeLock.notifyAll();
}
for (int id = 0; id < ID_MAX; ++id) {
final SurfaceHelper surfaceHelper = mSurfaceHelpers[id];
if (surfaceHelper != null)
surfaceHelper.release();
mSurfaceHelpers[id] = null;
}
for (IVLCVout.Callback cb : mIVLCVoutCallbacks)
cb.onSurfacesDestroyed(this);
if (mSurfaceCallback != null)
mSurfaceCallback.onSurfacesDestroyed(this);
if (AndroidUtil.isJellyBeanOrLater)
mSurfaceTextureThread.release();
}
@MainThread
private void onSurfaceCreated() {
if (mSurfacesState.get() != SURFACE_STATE_ATTACHED)
throw new IllegalArgumentException("invalid state");
final SurfaceHelper videoHelper = mSurfaceHelpers[ID_VIDEO];
final SurfaceHelper subtitlesHelper = mSurfaceHelpers[ID_SUBTITLES];
if (videoHelper == null)
throw new NullPointerException("videoHelper shouldn't be null here");
if (videoHelper.isReady() && (subtitlesHelper == null || subtitlesHelper.isReady())) {
mSurfacesState.set(SURFACE_STATE_READY);
for (IVLCVout.Callback cb : mIVLCVoutCallbacks)
cb.onSurfacesCreated(this);
if (mSurfaceCallback != null)
mSurfaceCallback.onSurfacesCreated(this);
}
}
/**
* Cancel the dump of the Uri.
* Don't call this method if you already received the {@link Listener#onFinish(boolean)} callback.
*/
@MainThread
public void cancel() {
mMediaPlayer.stop();
mMediaPlayer.release();
mLibVLC.release();
}
@MainThread
void removeListener(@NonNull final LoadListener<T> listener) {
if (listenerObserverMap.containsKey(listener)) {
Observer<T> observer = listenerObserverMap.remove(listener);
liveData.removeObserver(observer);
}
}
/**
* Browse to the specified local path starting with '/'.
*
* @param path
* @param flags see {@link Flag}
*/
@MainThread
public void browse(String path, int flags) {
final Media media = new Media(mLibVlc, path);
browse(media, flags);
media.release();
}
/**
* 设置倒数时间
*
* @param value 显示的值。
* 1、为0时,显示为 发送验证码
* 2、其他数字,则正常显示
*/
@MainThread
private void setSendCodeText(long value) {
if (value <= 0) {
tvSendCode.setText(getString(R.string.forget_send_code));
return;
}
tvSendCode.setText(
String.format(getString(R.string.forget_backwards),
value
));
}
/**
* Release the MediaBrowser.
*/
@MainThread
public void release() {
reset();
if (!mAlive)
throw new IllegalStateException("MediaBrowser released more than one time");
mLibVlc.release();
mAlive = false;
}
/**
* Adds the given observer to the observers list. This call is similar to
* {@link LiveEvent#observe(LifecycleOwner, Observer)} with a LifecycleOwner, which
* is always active. This means that the given observer will receive all events and will never
* be automatically removed. You should manually call {@link #removeObserver(Observer)} to stop
* observing this LiveData.
* While LiveData has one of such observers, it will be considered
* as active.
* <p>
* If the observer was already added with an owner to this LiveData, LiveData throws an
* {@link IllegalArgumentException}.
*
* @param observer The observer that will receive the events
*/
@MainThread
public void observeForever(@NonNull Observer<T> observer) {
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
wrapper.mLastVersion = getVersion();
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing instanceof LiveEvent.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
@MainThread
public void observeStickyForever(@NonNull Observer<T> observer) {
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing instanceof LiveEvent.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
/**
* Create a Dumper that will download an Uri into a local filesystem path
* @param uri the Uri to dump
* @param filepath local filesystem path where to dump the Uri
* @param listener listener in order to be notified when the dump is finished
*/
@MainThread
public Dumper(Uri uri, String filepath, Listener listener) {
if (uri == null || filepath == null || listener == null)
throw new IllegalArgumentException("arguments shouldn't be null");
mListener = listener;
ArrayList<String> options = new ArrayList<>(8);
options.add("--demux");
options.add("dump2,none");
options.add("--demuxdump-file");
options.add(filepath);
options.add("--no-video");
options.add("--no-audio");
options.add("--no-spu");
options.add("-vv");
mLibVLC = new LibVLC(null, options);
final Media media = new Media(mLibVLC, uri);
mMediaPlayer = new MediaPlayer(media);
mMediaPlayer.setEventListener(new MediaPlayer.EventListener() {
@Override
public void onEvent(MediaPlayer.Event event) {
switch (event.type) {
case MediaPlayer.Event.Buffering:
mListener.onProgress(event.getBuffering());
break;
case MediaPlayer.Event.EncounteredError:
case MediaPlayer.Event.EndReached:
mListener.onFinish(event.type == MediaPlayer.Event.EndReached);
cancel();
break;
}
}
});
media.release();
}
/**
* Removes all observers that are tied to the given {@link LifecycleOwner}.
*
* @param owner The {@code LifecycleOwner} scope for the observers to be removed.
*/
@SuppressWarnings("WeakerAccess")
@MainThread
public void removeObservers(@NonNull final LifecycleOwner owner) {
assertMainThread("removeObservers");
for (Map.Entry<Observer<T>, ObserverWrapper> entry : mObservers) {
if (entry.getValue().isAttachedTo(owner)) {
removeObserver(entry.getKey());
}
}
}
/**
* Browse to the specified uri.
*
* @param uri
* @param flags see {@link Flag}
*/
@MainThread
public void browse(Uri uri, int flags) {
final Media media = new Media(mLibVlc, uri);
browse(media, flags);
media.release();
}
@MainThread
private void observeInternal(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
ObserverWrapper<T> observerWrapper = new ObserverWrapper<>(observer);
observerWrapper.preventNextEvent = liveData.getVersion() > ExternalLiveData.START_VERSION;
liveData.observe(owner, observerWrapper);
logger.log(Level.INFO, "observe observer: " + observerWrapper + "(" + observer + ")"
+ " on owner: " + owner + " with key: " + key);
}
@MainThread
public void dismiss() {
if (mId != 0) {
nativeDismiss(mId);
mId = 0;
}
}
@MainThread
private void removeObserverInternal(@NonNull Observer<T> observer) {
Observer<T> realObserver;
if (observerMap.containsKey(observer)) {
realObserver = observerMap.remove(observer);
} else {
realObserver = observer;
}
liveData.removeObserver(realObserver);
}
/**
* Discover all networks shares
*/
@MainThread
public void discoverNetworkShares() {
reset();
final MediaDiscoverer.Description descriptions[] =
MediaDiscoverer.list(mLibVlc, MediaDiscoverer.Description.Category.Lan);
if (descriptions == null)
return;
for (MediaDiscoverer.Description description : descriptions) {
Log.i(TAG, "starting " + description.name + " discover (" + description.longName + ")");
startMediaDiscoverer(description.name);
}
}
/**
* Get a media at a specified index. Should be released with {@link #release()}.
*/
@MainThread
public Media getMediaAt(int index) {
if (index < 0 || index >= getMediaCount())
throw new IndexOutOfBoundsException();
final Media media = mBrowserMediaList != null ? mBrowserMediaList.getMediaAt(index) :
mDiscovererMediaArray.get(index);
media.retain();
return media;
}
/**
* Post an answer
*
* @param action 1 for first action, 2 for second action
*/
@MainThread
public void postAction(int action) {
if (mId != 0) {
nativePostAction(mId, action);
mId = 0;
}
}
@MainThread
public void setValue(@Nullable T t) {
mPending.set(true);
super.setValue(t);
}
/**
* Used for cases where T is Void, to make calls cleaner.
*/
@MainThread
public void call() {
setValue(null);
}