我开始构建一个应用程序,某些活动将从服务器获取和发布数据。例如,登录活动将发布用户名和密码以尝试登录,列表活动将从服务器数据库加载项目。现在,对于服务器和应用程序之间的每次通信,我使用一个AsyncTask
来执行此操作。为了重用目的,我有一个基类MyAsyncTask
类,每个实际任务都扩展它。
public class MyAsyncTask extends AsyncTask<String, Integer, String>{
protected String path;
public MyAsyncTask(Activity activity, String path){
this.path=path;//each task will connect to its own url path
}
@Override
protected String doInBackground(String... params) {
String ret=null;
try {
ret=postData(params);
} catch (IOException e) {
e.printStackTrace();
}
return ret;
}
public String postData(String... params) throws IOException{
String httpUrl=Constants.SERVER_URL+path;
HttpPost httpRequest=new HttpPost(httpUrl);
List<NameValuePair> httpparams=formHttpParams(params);
//create HttpClient and connect to server and post data
... ...
}
public ArrayList<NameValuePair> formHttpParams(String params[]){
return new ArrayList<NameValuePair>();//sub classes need to override the parameter assignment
}
//protected void onPostExecute(String result) {}//override this for response handling
}
我的问题是,我可以使用一个AsyncTask
来执行此操作吗?否则,我会有很多子类扩展MyAsyncTask
。这是处理Android网络应用的正确方法吗? (目前,如果我想做一个单独的类,我将有复杂的参数解析过程并管理多个相应的路径。)
另外,如果我仍然使用多个子类来扩展这个基类,我的应用程序和服务器之间会有一个“会话”,所以我可以在服务器的会话部分保存用户身份信息(如用户名)吗? (这是一个“侧面”的问题,因为我当然可以试验这个......)
答案 0 :(得分:1)
很久以前我遇到过同样的问题。从那时起,我实现了自己的类来从服务器发布/获取JSON数据。当我进行调用时,我使用一个接口来回调活动或片段,这样我只需要自定义回调,而不是整个Asynctask。类似的东西:
/**
* An interface for calling back from service
*
* @author
*
*/
public interface JSONCallback {
public void onError(String error);
/**
* A JSONObject or a JSONArray
* @param object
*/
public void onSuccess(Object object);
}
public static class PostTask extends AsyncTask<String, String, Integer>{
Activity activity;
String message;
ProgressDialog pDialog;
Object object = null;
HttpEntity entity;
JSONCallback callback;
boolean getJSONArray;
private String error = null;
private HashMap<String, String> headers;
public HashMap<String, String> getHeaders() {
return headers;
}
public void setHeaders(HashMap<String, String> headers) {
this.headers = headers;
}
public PostTask(Activity activity, String message, HttpEntity entity, JSONCallback callback){
this.activity = activity;
this.message = message;
this.entity = entity;
this.callback = callback;
this.getJSONArray = false;
}
public PostTask(Activity activity, String message, HttpEntity entity, JSONCallback callback, boolean getJSONArray){
this.activity = activity;
this.message = message;
this.entity = entity;
this.callback = callback;
this.getJSONArray = getJSONArray;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
if(message != null){
pDialog = ProgressDialog.show(activity, null, message, true, true, new DialogInterface.OnCancelListener() {
public void onCancel(DialogInterface dialog) {
cancel(true); //cancel this task
}
});
}
}
@Override
protected Integer doInBackground(String... params) {
try {
object = getJSONPOST(activity, params[0], entity, getJSONArray, headers);
return 0;
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
@Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
try {
pDialog.dismiss();
} catch (Exception e) {
}
if(callback!=null && !activity.isFinishing()){
if(result == 0){
callback.onSuccess(object);
}else{
callback.onError(error);
}
}
}
}
public static Object getJSONPOST(Context context, String url, HttpEntity entity, boolean isJSONArray, HashMap<String, String> headers) throws ClientProtocolException, IOException, JSONException{
DefaultHttpClient client = new DefaultHttpClient();
try{
client.getCookieStore().clear();
}catch(Exception e){
e.printStackTrace();
}
HttpPost post = new HttpPost(url);
post.setEntity(entity);
// post.setHeader( "content-type", "application/json" );
// post.setHeader( "charset", "UTF-8" );
if(headers != null){
Set<String> keys = headers.keySet();
for(String key:keys){
// Log.d("", "Header name: "+key+", header value: "+headers.get(key));
post.setHeader(key, headers.get(key));
}
}
HttpResponse response = client.execute(post);
// Log.d(“”,“响应错误代码:”+ response.getStatusLine()。getStatusCode()); InputStream = = response.getEntity()。getContent(); BufferedReader reader = new BufferedReader(new InputStreamReader( 是,“UTF-8”),8); StringBuilder sb = new StringBuilder(); String line = null; while((line = reader.readLine())!= null){ sb.append(line +“\ n”); } is.close(); 如果(!isJSONArray) 返回新的JSONObject(sb.toString()); 其他 返回新的JSONArray(sb.toString()); }
请注意,此模型仅用于解释,应该用于创建您自己的模型,以便您可以满足您的需求。我已经为GET,PUT和DELETE方法做了这个。
方面问题:您可以从HttpClient获取CookieManager(如果您使用cookie来保持会话)并将它们存储在全局成员中,或者即使应用程序关闭也会保留它们。这一切都取决于你在做什么。
希望它有所帮助。
答案 1 :(得分:0)
您可以尝试使用Square中的Retrofit REST客户端。 AsyncTask的主要问题是您无法轻松处理方向更改,但如果您想使用它,则可以在AsyncTask构造函数中传递Command。
public interface Command {
public Object execute();
}
public class MyTask extends AsyncTask<String, String, Object> {
private Exception e;
private Command command;
public MyTask(Command command) {
this.command = command;
}
public Object doInBackground() {
try {
return command.execute();
} catch(Exception e) {
this.e = e;
}
return null;
}
public void onPostExecute(final Object result) {
//Handle your result
}
}
类似的东西。