我对 java 和 Android 还比较陌生,正在使用 Android 示例代码 MediaBrowserService。
我利用该代码了解 MediaController 和 MediaSession 如何协同工作。回调用于该使用模式。我在该示例中还看到,用户定义的类也使用回调范例。
我有一个关于线程限制的问题。 例如,在公共(public)类 MusicProvider 中声明如下:
public interface Callback {
void onMusicCatalogReady(boolean success);
}
在同一类中有以下引用:
private void retrieveMediaAsync(Callback callback) {
initializationLock.lock();
//...
//code removed
//...
if (callback != null) {
Log.w(" CB_REF1",":");
callback.onMusicCatalogReady(mCurrentState == State.INITIALIZED);
}
}
}
和:
public void retrieveMedia(final Callback callback) {
//...
//code removed
//...
Log.w(" CB_REF2",":");
callback.onMusicCatalogReady(true);
return;
}
然后在公共(public)类 MusicService(扩展 MediaBrowserService)中有以下定义:
public void onCreate() {
//...
//code removed
//...
super.onCreate();
Log.w(" CB_DEF2",":");
mMusicProvider.retrieveMedia(new MusicProvider.Callback() {
@Override
public void onMusicCatalogReady(boolean success) {
mState = success ? PlaybackState.STATE_NONE : PlaybackState.STATE_ERROR;
}
});
和:
public void onLoadChildren(final String parentMediaId, final Result<List<MediaItem>> result) {
//...
//code removed
//...
Log.w(" CB_DEF1",":");
mMusicProvider.retrieveMedia(new MusicProvider.Callback() {
@Override
public void onMusicCatalogReady(boolean success) {
if (success) {
loadChildrenImpl(parentMediaId, result);
} else {
updatePlaybackState(getString(R.string.error_no_metadata));
result.sendResult(new ArrayList<MediaItem>());
}
}
});
然后我运行应用程序,在 Logcat 窗口中输出以下内容:
03-01 12:19:32.607 1929-1929/com.example.android.mediabrowserservice W/CB_DEF2﹕ :
03-01 12:19:32.794 1929-1929/com.example.android.mediabrowserservice W/CB_DEF2﹕ :
03-01 12:19:32.957 1929-1929/com.example.android.mediabrowserservice W/CB_DEF1﹕ :
03-01 12:19:33.294 1929-2053/com.example.android.mediabrowserservice W/CB_REF1﹕ :
03-01 12:19:45.329 1929-1929/com.example.android.mediabrowserservice W/CB_DEF2﹕ :
03-01 12:19:45.347 1929-1929/com.example.android.mediabrowserservice W/CB_DEF1﹕ :
03-01 12:19:45.426 1929-2033/com.example.android.mediabrowserservice W/CB_REF1﹕ :
03-01 12:19:45.428 1929-2033/com.example.android.mediabrowserservice W/CB_REF1﹕ :
03-01 12:19:47.622 1929-1929/com.example.android.mediabrowserservice W/CB_DEF2﹕ :
03-01 12:19:47.643 1929-1929/com.example.android.mediabrowserservice W/CB_DEF1﹕ :
03-01 12:19:47.732 1929-2053/com.example.android.mediabrowserservice W/CB_REF1﹕ :
03-01 12:19:47.734 1929-2033/com.example.android.mediabrowserservice W/CB_REF1﹕ :
所以我可以看到(并且有点理解)如何通过将特定定义注册为回调来根据需要重新定义回调函数。
我的问题与多线程相关的行为有关。
注册不同回调方法的能力是否意味着所有这些注册都必须发生在与回调调用相同的线程中,以确保调用回调时回调注册不处于某个中间状态?
如果不是这种情况,那么在我看来,当回调被调用时,注册回调的指令可能处于某种中间状态,我不确定这将如何在 Android 环境中处理。
感谢您考虑我的问题。 吉姆
最佳答案
Android遵循单线程模型,也就是说,所有与UI相关的操作都只发生在主线程上,所有非UI操作都需要显式地在单独的线程上执行。因此,回调的线程同步并不是大多数人谈论的话题。如果我们在两个不同线程上的操作之间发送回调,则将有必要这样做。框架设计者采用单线程策略正是因为线程同步对大多数程序员来说是一个棘手的问题。
您确实提出了一个有趣的问题,作为回答,以这种方式(由框架)同步的回调示例是:
AsyncTask
的doInBackground()
和onPostExecute()
方法。- Volley
Request
的onResponse()
和onError()
方法。
但是,这些都不是您所描述类型的真正接口(interface)回调。这些是在派生类中重写的虚方法。我必须承认,到目前为止,我从未在 Android 应用程序开发中看到过在两个线程之间同步的接口(interface)回调。
关于java - Android中不同线程之间的同步回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28797825/