AsyncTask Android – 设计模式和返回值

我正在编写一个validation外部Web服务器上的登录凭据的应用程序 – 所以我有一个基本的问题:创建一个登录屏幕,当提交时会在后台向服务器发送HTTP请求而不会导致UI挂起 – 同时提供对用户的ProgressDialog。

我的问题在于,我想编写一个扩展AsyncTask的通用HTTP Request类,所以当我调用.execute()我将传递String参数,这些参数可能包含类似’post’的内容,并且当doInBackground时,这将看到’post’字符串然后将这些参数转发到我class级的相应调用中。 伪代码就像是

 public class HTTPOperations extends AsyncTask { doInBackground(String... string1,additionalParams) { if string1.equals "post" response = httpPost(additionalParams) return response; } httpPost(params) { // do http post request } } 

这是我能想到的,除了为我希望制作的每个HTTP Post / GET等请求创建一个类并扩展ASyncTask …

这引出了我的下一个问题,如果HTTP POST成功并返回一个身份validation令牌,我该如何访问此令牌?

因为新的httpOperations.execute(),不会从doInBackground返回字符串,而是返回值types

对不起,如果这没有意义,我根本无法解决这个问题。 如果需要,请询问详细说明。 AsyncTask的设计模式和想法受到了极大的欢迎。

如果您正在为此类设计可重用任务,则需要确定可重用的返回types。 这是您的设计决定。 问问自己,“我的HTTP操作在它们被调用的机制和处理数据的机制中是否相似?” 如果是这样,您可以设计一个类来执行这两个操作。 如果没有,您可能需要针对不同远程操作的不同类。

在我个人的使用中,我有一个对象,我附加键值对,常见的返回types是HttpEntity 。 这是HTTP Get和Post的返回types,这似乎在我的场景中正常工作,因为我在exception的HTTP结果情况下抛出exception,例如404.此设置的另一个好处是将参数附加到get的代码或者post非常相似,所以这个逻辑很容易构建。


一个例子就是这样(psuedo):

 public interface DownloadCallback { void onSuccess(String downloadedString); void onFailure(Exception exception); } 

然后在你的代码中,你去哪里下载:

 DownloadCallback dc = new DownloadCallback(){ public void onSuccess(String downloadedString){ Log.d("TEST", "Downloaded the string: "+ downloadedString); } public void onFailure(Exception e){ Log.d("TEST", "Download had a serious failure: "+ e.getMessage()); } } DownloadAsyncTask dlTask = new DownloadAsyncTask(dc); 

然后在DownloadAsyncTask的构造函数中,存储DownloadCallback,并在下载完成或失败时,调用与该事件对应的下载回调方法。 所以…

 public class DownloadAsyncTask extends AsyncTask (){ DownloadCallback dc = null; DownloadAsyncTask(DownloadCallback dc){ this.dc = dc; } ... other stuff ... protected void onPostExecute(String string){ dc.onSuccess(string); } } 

我要重申,我认为为了自己的利益,你应该回传HttpEntities。 字符串现在似乎是一个好主意,但是当你想要在http调用后面做更复杂的逻辑时,它确实会导致麻烦。 当然,这取决于你。 希望这会有所帮助。

假设web api的数据格式是json,我的设计模式:

普通class
1.MyAsyncTask:扩展AsyncTask
2.BackgroundBase:服务器的参数
3.API_Base:来自服务器的参数
4.MyTaskCompleted:回调接口

 public class MyAsyncTask extends AsyncTask { private ProgressDialog pd ; private MyTaskCompleted listener; private Context cxt; private Class resultType; private String url; private int requestCode; public MyAsyncTask(MyTaskCompleted listener, Class resultType, int requestCode, String url){ this.listener = listener; this.cxt = (Context)listener; this.requestCode = requestCode; this.resultType = resultType; this.url = url; } public MyAsyncTask(MyTaskCompleted listener, Class resultType, int requestCode, String url, ProgressDialog pd){ this(listener, resultType, requestCode, url); this.pd = pd; this.pd.show(); } @Override protected APIClass doInBackground(BackgroundClass... params) { APIClass result = null; try { //do something with url and params, and get data from WebServer api BackgroundClass oParams = params[0]; String sUrl = url + "?d=" + URLEncoder.encode(oParams.getJSON(), "UTF-8"); String source = "{\"RtnCode\":1, \"ResultA\":\"result aaa\", \"ResultB\":\"result bbb\"}"; //to see progressdialog Thread.sleep(2000); result = new com.google.gson.Gson().fromJson(source, resultType); } catch (Exception e) { e.printStackTrace(); } return result; } @Override protected void onPostExecute(APIClass result) { super.onPostExecute(result); try { if(pd != null && pd.isShowing()) pd.dismiss(); API_Base oApi_Base = (API_Base)result; listener.onMyTaskCompleted(result , this.requestCode); } catch (Exception e) { e.printStackTrace(); } } } public class API_Base { public int RtnCode; public String getJSON(Context context) throws Exception { return new com.google.gson.Gson().toJson(this); } public String toString(){ StringBuilder sb = new StringBuilder(); for (Field field : this.getClass().getFields()) { try { field.setAccessible(true); Object value = field.get(this); if (value != null) { sb.append(String.format("%s = %s\n", field.getName(), value)); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } return sb.toString(); } } public class BackgroundBase { public String getJSON() throws Exception { return new com.google.gson.Gson().toJson(this); } } public interface MyTaskCompleted { void onMyTaskCompleted(API_Base oApi_Base, int requestCode) ; } 

例如,让我们在一个活动中调用两个api
假设:
API 1. http://www.google.com/action/a
输入参数:ActionA
输出参数:RtnCode,ResultA

API 2. http://www.google.com/action/b
输入参数:ActionB
输出参数:RtnCode,ResultB

类示例:
1.MyActivity:扩展Activity并实现MyTaskCompleted
2.MyConfig:实用程序类,我在这里设置requestCode
3.BackgroundActionA,BackgroundActionB:api的输入参数的模型类
4.API_ActionA,API_ActionB:api输出参数的模型类

 public class MyActivity extends Activity implements MyTaskCompleted { ProgressDialog pd; Button btnActionA, btnActionB; TextView txtResult; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.my_layout); btnActionA = (Button)findViewById(R.id.btn_actionA); btnActionB = (Button)findViewById(R.id.btn_actionB); txtResult = (TextView)findViewById(R.id.txt_result); btnActionA.setOnClickListener(listener_ActionA); btnActionB.setOnClickListener(listener_ActionB); pd = new ProgressDialog(MyActivity.this); pd.setTitle("Title"); pd.setMessage("Loading"); } Button.OnClickListener listener_ActionA = new Button.OnClickListener(){ @Override public void onClick(View v) { //without ProgressDialog BackgroundActionA oBackgroundActionA = new BackgroundActionA("AAA"); new MyAsyncTask(MyActivity.this, API_ActionA.class, MyConfig.RequestCode_actionA, "http://www.google.com/action/a").execute(oBackgroundActionA); } }; Button.OnClickListener listener_ActionB = new Button.OnClickListener(){ @Override public void onClick(View v) { //has ProgressDialog BackgroundActionB oBackgroundActionB = new BackgroundActionB("BBB"); new MyAsyncTask(MyActivity.this, API_ActionB.class, MyConfig.RequestCode_actionB, "http://www.google.com/action/b", MyActivity.this.pd).execute(oBackgroundActionB); } }; @Override public void onMyTaskCompleted(API_Base oApi_Base, int requestCode) { // TODO Auto-generated method stub if(requestCode == MyConfig.RequestCode_actionA){ API_ActionA oAPI_ActionA = (API_ActionA)oApi_Base; txtResult.setText(oAPI_ActionA.toString()); }else if(requestCode == MyConfig.RequestCode_actionB){ API_ActionB oAPI_ActionB = (API_ActionB)oApi_Base; txtResult.setText(oAPI_ActionB.toString()); } } } public class MyConfig { public static String LogTag = "henrytest"; public static int RequestCode_actionA = 1001; public static int RequestCode_actionB = 1002; } public class BackgroundActionA extends BackgroundBase { public String ActionA ; public BackgroundActionA(String actionA){ this.ActionA = actionA; } } public class BackgroundActionB extends BackgroundBase { public String ActionB; public BackgroundActionB(String actionB){ this.ActionB = actionB; } } public class API_ActionA extends API_Base { public String ResultA; } public class API_ActionB extends API_Base { public String ResultB; } 

这种设计模式的优势
1.多重api的优势
2.只需为新api添加模型类,例如:BackgroundActionA和API_ActionA
3.在回调函数中确定不同requestCode的API:onMyTaskCompleted