我已经开发了许多提出Web服务请求的Android应用程序,总是采用以下方法:
在每个需要发出网络服务请求的活动中,我定义了一个在AsyncTask
中显示ProgressDialog
的内部onPreExecute()
,在doInBackground
中进行了网络服务调用,并解除progressDialog并从onPostExecute()
更新UI中的结果。
我担心的是:有更好(更短)的方式吗?在每个活动中重复所有代码是否有意义?我一直在谷歌搜索,但我什么都没找到。
我的问题是:我无法定义Callback接口吗?例如这一个:
public interface RequestCallback {
public void onSuccess(Whatever whatever);
public void onError(ErrorCode errorCode, String message);
}
...然后定义一个外部类,例如AsyncRequest
,它包装了AsyncTask定义和ProgressDialog show()
和dismiss()
语句。因此,所有活动只需要实例化该类,并传递以下参数:
1)运行Web服务的方法
2)包含Web服务该方法的所有参数的Bundle
3)RequestCallback实例(可以是匿名内联实例,我可以从onSuccess()
更新UI)
4)Activity的上下文(显示ProgressDialog()所必需的,所以我仍然需要一种方法来防止配置更改异常等等...),
你觉得这个设计好吗?它可以节省数百行代码......
答案 0 :(得分:1)
您的方法就是我在项目中所做的。它就像你说的那样保存了很多代码,我对它没有任何抱怨。但是我想告诉你一些问题:
AsyncTask
的新实例,以避免回调。对于进度对话框,我将其用作Singleton
,因为您没有同时显示多个对话框。当您调用后台作业时,将显示该对话框,并且将在回调中关闭该对话框。这是我做的:
private void showProgressDialog(String strMess){
if(null == progressDialog){
progressDialog = new ProgressDialog(MainActivity.this);
}
if(!progressDialog.isShowing()){
progressDialog.setMessage(strMess);
progressDialog.show();
}
}
private void hideProgressDialog(){
if(null != progressDialog && progressDialog.isShowing()){
progressDialog.dismiss();
}
}
void someMethod(){
showProgressDialog("Loading...");
doBackgroundJob(param, new RequestCallBack() {
public void onRequestCompleted(String message, boolean isSuccess) {
hideProgressDialog();
if(isSuccess){
}else{
//do something on error
}
}
});
}
这是一个可选的,我定义了一个通知而不是特定类的接口,对于我使用一个类的每个响应,所以在基类中,我不关心响应是什么。这是它:
public interface OnRequestCompleted<TResponse> {
void requestCompleted(TResponse response);
}
public abstract class BaseRequest<TResponse> implements IRequest{
protected OnRequestCompleted<TResponse> delegate;
protected Class<TResponse> responseClass;
@Override
public void send() {
new HttpTask().execute();
}
private class HttpTask extends AsyncTask<Void, Void, String> {
//...
@Override
protected void onPostExecute(String result) {
if (null != response && null != delegate) {
delegate.requestCompleted(response);
}
}
}
// the response example
public class GroupResponse {
public static class Clip {
public int clipId;
public String detail;
}
public static class Movie {
public int movieId;
public String detail;
}
}
在BaseRequest
的子类中,我将准确地告诉它响应类是什么(Movie,Clip ...)
希望这有帮助。
答案 1 :(得分:0)
如果你已经使用它并且它适合你,那么是的,它是有意义的,使它通用,并节省重新实现相同的事情数十次的时间(和错误)。如果您发现自己复制粘贴大部分代码而几乎没有差异,则应将其转换为库函数或某种类。否则,如果您以后发现问题,则必须在十几个地方修复它。如果你想到一个更好的方法来做事情,这甚至不重要 - 它仍然比一个地方更容易改变它。
我对你的解决方案唯一真正的问题是我不会向它添加进度条 - 我将在调用代码和onSuccess / onError实现中处理它。这样你也可以将它重用于不需要建立UI的后台调用。我尽量保持我的UI决策尽可能远离数据抓取代码,MVC模式很好。