我使用Retrofit从我的RESTful接收json,这很好。我试图实现Loader类以使数据加载逻辑更加清晰,而不是将其放入onCreateView方法来加载它,这对于加载数据来说并不是一个明确的逻辑。但是,如果我尝试使用AsyncTaskLoader(一个应该从异步进程接收数据的那个)进行改造,我发现有点困惑。我坚持这一点。 Retrofit已经是一个异步过程,我想我应该在AsyncLoader类的改进中使用异步调用或同步调用。
package generic.fragment;
import android.databinding.ViewDataBinding;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import java.util.ArrayList;
import java.util.List;
import generic.adapter.BaseListAdapter;
public abstract class SwipedLoaderListFragment<Bean, Adapter extends BaseListAdapter<Bean, ? extends ViewDataBinding>> extends SwipedListFragment<Bean, Adapter> implements LoaderManager.LoaderCallbacks<List<Bean>> {
public SwipedLoaderListFragment(FragConfig pFragConfig) {
super(pFragConfig);
}
@Override
public List<Bean> loadData(String query) {
List<Bean> list = new ArrayList<>();
return list;
}
@Override
public void refreshing() {
getLoaderManager().restartLoader(0, null, this);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(0, null, this).forceLoad();
}
@Override
public void onLoadFinished(Loader<List<Bean>> loader, List<Bean> data) {
mAdapter.clear();
mAdapter.addAll(data);
}
@Override
public void onLoaderReset(Loader<List<Bean>> loader) {
mAdapter.clear();
}
}
这是我用过的片段。
public class LocListFragment extends SwipedLoaderListFragment<String, SimpleStringAdapter> {
public LocListFragment() {
super(new FragConfigBuilder(R.layout.swiped_list).setEnableSwipe(false).setFilterable(true).setEnableDivider(true).build());
}
@Override
public void query(String query) {
super.query(query);
mAdapter.filter(query);
}
@Override
public void queryWhenTextChanged(String query) {
super.queryWhenTextChanged(query);
mAdapter.filter(query);
}
@Override
public SimpleStringAdapter initListAdapter() {
return new SimpleStringAdapter(getActivity(), loadData("")) {
@Override
public ListItemStringBinding bind(ListItemStringBinding pBinding, String pS, int pPosition) {
pBinding.setText(pS);
return pBinding;
}
};
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent lIntent = new Intent();
lIntent.putExtra(SCConstants.PARAM_LOC, mAdapter.getItem(position));
getActivity().setResult(Activity.RESULT_OK, lIntent);
getActivity().finish();
}
@Override
public String getHintStr() {
return "Input Location";
}
@Override
public String getSearchTitle() {
return "Location Search";
}
@Override
public Loader<List<String>> onCreateLoader(int id, Bundle args) {
return new AsyncTaskLoader<List<String>>(getActivity()) {
@Override
public List<String> loadInBackground() {
//here will be the retrofit call
return null;
};
}
}
答案 0 :(得分:1)
由于Loader的loadInBackground
方法已经异步,因此使用同步改装调用可能更容易(即使用execute
而不是enqueue
)。
要使您的装载机正常工作,您还需要覆盖onStartLoading
。实现可能如下所示:
public class MyLoader<List<String>> extends AsyncTaskLoader {
List<String> mResult;
@Override
public List<String> loadInBackground() {
mResult = myHttpApi.execute()...
return mResult;
}
@Override
protected void onStartLoading() {
if (mResult != null) {
deliverResult(mResult);
}
if (mResult == null || takeContentChanged()) {
forceLoad();
}
}
}