如何为联网的Android应用程序设计AsyncTasks

时间:2014-09-24 02:52:49

标签: android android-asynctask

我开始构建一个应用程序,某些活动将从服务器获取和发布数据。例如,登录活动将发布用户名和密码以尝试登录,列表活动将从服务器数据库加载项目。现在,对于服务器和应用程序之间的每次通信,我使用一个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网络应用的正确方法吗? (目前,如果我想做一个单独的类,我将有复杂的参数解析过程并管理多个相应的路径。)

另外,如果我仍然使用多个子类来扩展这个基类,我的应用程序和服务器之间会有一个“会话”,所以我可以在服务器的会话部分保存用户身份信息(如用户名)吗? (这是一个“侧面”的问题,因为我当然可以试验这个......)

2 个答案:

答案 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
    }
}

类似的东西。