好的,这就是我想出的,它实际上似乎工作得很好,并且可以在后台工作期间处理屏幕方向更改。这是我更新的HttpAsyncTaskLoader。
public class HttpAsyncTaskLoader<T extends ApiResponse> extends AsyncTaskLoader { private ApiClient mClient ; protected ApiRequest mRequest; private ApiResponse mResponse; private volatile boolean isExecuting = false; public HttpAsyncTaskLoader(Context context, ApiClient client, ApiRequest request) { super(context); mClient = client; mRequest = request; } protected ApiResponse executeRequest(ApiRequest request) { HttpResponse response = null; ResponseError error = null; JSonObject responseJson = null; try { isExecuting = true; Log.d(TAG, "executing api"); response = mClient.execute(request); Log.d(TAG, "got a response"); isExecuting = false; responseJson = new JSonObject(EntityUtils.toString(response.getEntity())); Log.d(TAG, "parsed response to json"); } catch (IOException e) { error = new ResponseError(e); } catch (URISyntaxException e) { error = new ResponseError(e); } catch (JSonException e) { error = new ResponseError(e); } finally { mClient.getConnectionManager().closeExpiredConnections(); isExecuting = false; mResponse = new ApiResponse(getContext().getResources(), response, responseJson, error); } return mResponse; } protected void onStartLoading() { super.onStartLoading(); if (takeContentChanged() || mResponse == null) { forceLoad(); } if (getResponse() != null) { deliverResult(getResponse()); } } public ApiResponse getResponse() { return mResponse; } @Override public void onCanceled(Object data) { super.onCanceled(data); if (isExecuting) { mClient.getConnectionManager().shutdown(); } } @Override public ApiResponse loadInBackground() { return executeRequest(mRequest); }}
请注意,在上面的示例中,onCanceled方法采用一个Object。如果尝试使用ApiResponse,则会出现编译错误。作为类型。另外,您必须像上面一样实现onStartLoading(如果结果对象为null,则调用forceLoad),否则不会调用loadInBackground
接下来是HttpAsyncTaskLoader子类的示例:
public class LoginAsyncTaskLoader extends HttpAsyncTaskLoader { private LoginResponse mLoginResponse; public LoginAsyncTaskLoader(Context context, ApiClient client, ApiRequest request) { super(context, client, request); } @Override public LoginResponse loadInBackground() { ApiResponse apiResponse = executeRequest(mRequest); mLoginResponse = new LoginResponse(apiResponse.getResources(), apiResponse.response, apiResponse.responseJson, apiResponse.getError()); return mLoginResponse; } @Override public ApiResponse getResponse() { return mLoginResponse; }}
这是使用此加载程序的活动:
public class LoginActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<LoginResponse> { private String username,password;@Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.login); Loader loader = getSupportLoaderManager().getLoader(0); if (loader != null) { getSupportLoaderManager().initLoader(0, null, this); } } public void loginSubmit(View button) { Bundle data = new Bundle(); data.putString("username", getUsername()); data.putString("password", getPassword()); getSupportLoaderManager().restartLoader(0, data, this); } @Override public Loader<LoginResponse> onCreateLoader(int i, Bundle bundle) { //might want to start a progress bar ApiClient client = new ApiClient(); LoginApi loginApi = new LoginApi(bundle.getString("username"), bundle.getString("password")); return new LoginAsyncTaskLoader(this, apiClient, loginApi); } @Override public void onLoadFinished(Loader<LoginResponse> loginLoader, LoginResponse loginResponse) { //handle result, maybe send to a new activity if response doesn't have an error } @Override public void onLoaderReset(Loader<LoginResponse> responseAndJsonHolderLoader) { //not sure if anything needs to be done here to do }}
请注意,虽然该加载器直到用户按下“登录”按钮才启动,但是如果已经进行了,则必须使用onCreate中的initLoader重新连接到加载器,以防它已经在进行中;否则,当您翻转方向时,您将不会收到任务完成的通知。
。
有趣的是,这似乎很好用,不需要使用TaskFragment。我还没有真正看到其他人为http做这些事情,所以也许有一些缺点,但似乎工作得很好。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)