2014-09-24 2 views
-2

Я начинаю создавать приложение, которое некоторые действия будут получать & после публикации данных с сервера. Например, в активности входа будет указано имя пользователя и пароль, чтобы попытаться войти в систему, активность списка будет загружать элементы из базы данных сервера. Теперь для каждой связи между сервером и приложением я использую один AsyncTask, чтобы сделать это. Для целей повторного использования у меня есть базовый класс MyAsyncTask, и каждая реальная задача расширяет его.Как спроектировать AsyncTasks для сетевых приложений Android

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? (В настоящее время, если я хочу сделать один класс, у меня будут сложные процессы анализа параметров и управление несколькими соответствующими путями.)

Кроме того, если я все еще использую несколько подклассов для расширения этого базового класса, будет ли один «сеанс» между моим приложением и сервером, поэтому я могу сохранить идентификационную информацию пользователя (например, имя пользователя) в части сеанса сервера? (Это вопрос «стороны», поскольку я могу поэкспериментировать с этим, конечно ...)

+1

Отъезд Volley .. и есть много других подобных ему. Не заново изобретайте колесо, особенно если вы никогда не строили автомобиль раньше. – 323go

+0

Приятно знать официальное решение Volley. Это должен быть неотъемлемый компонент вместе с AsyncTask ... PS, проклинайте этих downvoters, hah ... – mrmoment

+0

Android-Query - это вариант и кажется более простым в использовании для людей из Интернета и чистой Java, таких как я :) – mrmoment

ответ

0

Вы можете использовать Retrofit Клиент REST с площади. Основная проблема с AsyncTask, что вы не можете справиться с ориентацией, легко меняется, но если вы хотите ее использовать, вы можете передать Command в конструкторе AsyncTask.

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

Нечто подобное.

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 is = response.getEntity(). GetContent(); BufferedReader reader = new BufferedReader (новый InputStreamReader ( is, «UTF-8»), 8); StringBuilder sb = new StringBuilder(); Строка line = null; while ((line = reader.readLine())! = Null) { sb.append (строка + "\ n"); } is.close(); if (! IsJSONArray) вернуть новый JSONObject (sb.toString()); еще вернуть новый JSONArray (sb.toString()); }

Обратите внимание, что эта модель предназначена только для пояснения и должна использоваться для создания своих собственных, поэтому вы можете соответствовать вашим потребностям. Я сделал это для методов GET, PUT и DELETE.

Вопрос: Вы можете получить CookieManager из HttpClient (если вы используете файлы cookie для сохранения сеанса) и сохранить их в глобальном члене или сохранить их, даже если приложение закрывается. Все зависит от того, что вы делаете.

Надеюсь, это поможет.

Смежные вопросы