重用HttpUrlConnection和AsynTask来处理REST请求

时间:2015-05-29 20:40:04

标签: android rest android-asynctask

我有PostData类将数据lat, long,mac,..传输到从服务类发送给它的服务器。在PostData类中,正在使用AsyncTaskHttpURLConnection处理数据。

现在我有一个新活动,用户可以将查询发送到服务器。要实现这一点,我必须从服务器获取ArrayList<Integer>并创建类似复选框列表的内容,用户可以在其中选择所需的项目,然后将数据发送到服务器以检索结果。

我是否可以实施新的AsyntaskHttpURLConnection来实现这一目标,或者我必须在AsynTask课程中使用HttpURLCOnnectionPOstData

我感谢任何帮助。

我的PostData课程:

public class PostData {
    String jSONString;
    private AsyncTaskCallback callback;

    public PostData(AsyncTaskCallback callback) {
        this.callback = callback;
    }

    public String getjSONString() {
        return jSONString;

    }

    public void setjSONString(String jSONString) {
        this.jSONString = jSONString;
    }

    public void post_data(String jSONString, Context context) {
        this.jSONString = jSONString;

        new MyAsyncTask(context).execute(jSONString);

    }

    class MyAsyncTask extends AsyncTask<String, Integer, ArrayList<Integer>> {
        final Context mContext;
        ArrayList<Integer> routes = new ArrayList<Integer>();
        double distance;

        public MyAsyncTask(Context context) {
            mContext = context;
        }

        @Override
        protected ArrayList<Integer> doInBackground(String... params) {
            BufferedReader reader = null;

            try {

                URL myUrl = new URL(
                        "https://bustracker.rhcloud.com/webapi/test");

                HttpURLConnection conn = (HttpURLConnection) myUrl
                        .openConnection();
                conn.setRequestMethod("POST");
                conn.setDoOutput(true);
                conn.setConnectTimeout(10000);
                conn.setReadTimeout(10000);
                conn.setRequestProperty("Content-Type", "application/json");
                conn.connect();

                DataOutputStream wr = new DataOutputStream(
                        conn.getOutputStream());
                wr.writeBytes(params[0]);

                wr.close();

                StringBuilder sb = new StringBuilder();
                reader = new BufferedReader(new InputStreamReader(
                        conn.getInputStream()));
                String line;

                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");

                }

                Gson gson = new Gson();
                StopsJSON data = gson.fromJson(sb.toString(), StopsJSON.class);

                routes = data.getRoutes();
                distance = data.getDistance();
                System.out.println("The output of the StringBulder: "
                        + sb.toString());

            } catch (IOException e) {

                e.printStackTrace();
                return null;
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                        return null;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            return null;

        }

        protected void onPostExecute(ArrayList<Integer> result) {

             if (routes != null && !routes.isEmpty()) {
            callback.onAsyncTaskFinished(routes, distance);
             }else{
                 Log.e("123", "Avoiding null pointer, the routes are null!!!");
             }
        }

    }

}

1 个答案:

答案 0 :(得分:3)

这可能会让您走上一些代码重构的道路,但是对于有关REST请求的一般良好做法,您应该查看VolleyRetrofit,(还another SO question关于改进可能有帮助。)

这些库在性能方面非常有效,从长远来看会为您节省很多麻烦,它们会处理后台线程,并且您不一定需要明确使用HttpUrlConnection。

希望这会有所帮助。

修改

要进一步回答你的问题 - 如果你确实希望专门使用AsyncTask - 你应该将PostData类用作通用类,在你的情况下用于网络操作(也可能想要使它成为一个单身人士,并给它一个更通用的名称。)

并且您的实现看起来应该能够使用它,并且任何更正\更改\添加应该在PostData下的AsyncTask本身中进行,不需要另一个通用类,如果需要 - 您可以添加更多内部AsyncTask子类。

我(非常非常一般)的方向是:

public class NetworkData {
String jSONString;
private AsyncTaskCallback callback;

public NetworkData(AsyncTaskCallback callback) {
    this.callback = callback;
}

public String getjSONString() {
    return jSONString;

}

public void setjSONString(String jSONString) {
    this.jSONString = jSONString;
}

//let's say this is for post requests...
public void postData(String jSONString, Context context) {
    this.jSONString = jSONString;

    new MyPostTask(context).execute(jSONString);

}

//let's say this is for get requests...
public void getData(String jSONString, Context context) {
    this.jSONString = jSONString;

    new MyGetTask(context).execute(jSONString);

}

class MyPostTask extends AsyncTask<String, Integer, ArrayList<Integer>> {
    final Context mContext;
    ArrayList<Integer> routes = new ArrayList<Integer>();
    double distance;

    public MyPostTask(Context context) {
        mContext = context;
    }

    @Override
    protected ArrayList<Integer> doInBackground(String... params) 
    {
        try
        {
         //do you stuff for post requests...
        } catch (IOException e) 
        {
         //...
        } 
        finally 
            {
             //...
            }
        }
     }

class MyGetTask extends AsyncTask<String, Void, ArrayList<Object>> {
    final Context mContext;
    ArrayList<Object> routes = new ArrayList<Object>();

    public MyPostTask(Context context) {
        mContext = context;
    }

    @Override
    protected ArrayList<Object> doInBackground(String... params) 
    {
        try
        {
         //do you stuff for get requests...
        } 
        catch (IOException e) 
        {
         //...
        } 
        finally 
        {
         //...
        }
      }
    }
}

如果你选择使用Volley或Retrofit,那么继续使用通用类结构,只需修改它的实用程序并替换requset格式(即代替AsyncTask部分)。