gpt4 book ai didi

android - 并行运行两个 AsyncTaskLoader

转载 作者:行者123 更新时间:2023-11-30 02:55:29 25 4
gpt4 key购买 nike

我正在尝试创建一个将搜索结果加载到 fragment 列表中的搜索函数。问题是搜索向 API 发出了两个请求:一个针对类型 A,一个针对类型 B。

我的实现方式是创建一个包含两个 fragment 的 ViewPager,FragmentA 和 FragmentB。每个人都通过扩展 AsyncTaskLoader 的自定义加载器调用带有搜索查询的 API 端点,AsyncTaskLoader 执行 API 查询并返回结果。这作为异常(exception)工作; fragment 接收搜索结果并将它们显示在列表中。

我在这个构造中遇到的唯一问题是,虽然两个 fragment 都使用单独的 LOADER_ID 启动它们的加载器,但实际上只有 FragmentA 从 AsyncTaskLoader 调用 loadInBackground()只有当我滑动到 ViewPager 中的 FragmentB 时,它才会调用 restartLoader()(然后又调用 loadInBackground()),执行 API 请求搜索并返回结果。

我想并行运行两个加载器的原因是,当 FragmentB 有搜索结果时,ViewPager 应该显示 FragmentB。

搜索列表 fragment :

public class SearchListFragment extends Fragment implements LoaderManager.LoaderCallbacks<SearchResults> {

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().enableDebugLogging(BuildConfig.DEBUG);
if (mSearchType == SearchType.ARTIST) {
getLoaderManager().initLoader(R.id.search_artist_loader, null, this);
} else {
getLoaderManager().initLoader(R.id.search_track_loader, null, this);
}
BusProvider.getInstance().register(this);
}

@Override
public Loader<ApiResponse> onCreateLoader(int id, Bundle args) {
int offset = 0;
String query = null;
if (args != null) {
if (args.containsKey("offset")) {
offset = args.getInt("offset");
}
if (args.containsKey(SearchManager.QUERY)) {
query = args.getString(SearchManager.QUERY);
mSearchQuery = query;
}
}
Log.d(TAG, "onCreateLoader for " + mSearchType.name());
Log.d(TAG, "id: " + id);

SearchLoader loader = new SearchLoader(getActivity(), mSearchType, offset, query);
return loader;
}

@Override
public void onLoadFinished(Loader<SearchResults> loader, SearchResults data) {

if (data != null) {
if (data.mSampleList.isEmpty()) {
mNoResults.setVisibility(View.VISIBLE);
} else {
mAdapter.swapApiResponse(data);
mListView.setVisibility(View.VISIBLE);
}
mLoading.setVisibility(View.GONE);
} else {
Exception exception = ((SearchLoader) loader).getError();
if(exception != null) {
Log.e(TAG, exception.toString());
Log.e(TAG, exception.getMessage());
Log.e(TAG, exception.getLocalizedMessage());
}
mNoResults.setVisibility(View.VISIBLE);
mLoading.setVisibility(View.GONE);
}
}

@Override
public void onLoaderReset(Loader<ApiResponse> loader) {

}
}

自定义加载器:

public class SearchLoader extends AsyncTaskLoader<ApiResponse> {

private static final String TAG = SearchLoader.class.getSimpleName();
private SearchResults mApiResponse;
private SearchType mSearchType;
private int mOffset;
private String mSearchQuery;
private Exception error = null;

public SearchLoader(Context context, SearchType type, int offset, String query) {
super(context);
mSearchType = type;
mOffset = offset;
mSearchQuery = query;
}

@Override
public ApiResponse loadInBackground() {
try {
return tryLoadInBackground();
} catch (Exception e) {

error = e;
return null;
}
}

public ApiResponse tryLoadInBackground() throws Exception {
if (mSearchQuery != null) {
Map<String, String> parameters = Utils.parametersMap("q:" + mSearchQuery, "offset:" + String.valueOf(mOffset));
if (mSearchType == SearchType.ARTIST) {
return API.getRestAdapter().searchTypeA(parameters);
} else {
return API.getRestAdapter().searchTypeB(parameters);
}
}
return null;
}

@Override
protected void onStartLoading() {
Log.d(TAG, "onStartLoading for " + mSearchType.name());
if (mApiResponse != null) {
deliverResult(mApiResponse);
}
if (takeContentChanged() || mApiResponse == null) {
forceLoad();
}
}


@Override
protected void onStopLoading() {
cancelLoad();
}

@Override
public void onCanceled(ApiResponse data) {
// Attempt to cancel the current asynchronous load.
super.onCanceled(data);

onReleaseResources(data);
}

@Override
protected void onReset() {
// Ensure the loader has been stopped.
onStopLoading();


// At this point we can release the resources associated with 'apps' if needed
if (mApiResponse != null) {
onReleaseResources(mApiResponse);
mApiResponse = null;
}
}

@Override
public void deliverResult(ApiResponse data) {
if (isReset()) {
// An async query came in while the loader is stopped. We don't need the result
if (data != null) {
onReleaseResources(data);
}
return;
}
SearchResults oldData = mApiResponse;
mApiResponse = data;

if (isStarted()) {
// If the loader is currently started, we can immediately deliver a result
super.deliverResult(mApiResponse);
}

// At this point we can release the resources associated with 'oldApps' if needed;
// now that the new result is delivered we know that it is no longer in use
if (oldData != null && oldData != mApiResponse) {
onReleaseResources(oldData);
}
}

/**
* Helper function to take care of releasing resources associated with an actively loaded data set
*/
private void onReleaseResources(ApiResponse data) {
// For a simple list there is nothing to do
// but for a Cursor we would close it here
}

public Exception getError() {
return error;
}
}

最佳答案

关于android - 并行运行两个 AsyncTaskLoader,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23361765/

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