【问题标题】:Reuse HttpUrlConnection and AsynTask for REST requests为 REST 请求重用 HttpUrlConnection 和 AsynTask
【发布时间】:2015-08-12 20:33:55
【问题描述】:

我有 PostData 类将数据lat, long,mac,.. 传输到服务器,该服务器从服务类发送给它。在 PostData 类中,数据是在 AsyncTaskHttpURLConnection 的帮助下处理的。

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

我是否可以实现一个新的AsyntaskHttpURLConnection 来实现这一点,或者我必须在POstData 类中使用我的AsynTaskHttpURLCOnnection

感谢您的帮助。

我的 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!!!");
             }
        }

    }

}

【问题讨论】:

    标签: android rest android-asynctask


    【解决方案1】:

    这可能会让您走上一些代码重构的道路,但对于有关 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,则继续使用通用类结构,只需修改它的实用程序并替换请求集格式(即,而不是 AsyncTask 部分)。

    【讨论】:

    • 我完全同意你的观点,即使用专门用于简化事情的库。但是该实现仍然可能取代内部 post_data 的任何内容。问题本身是他是否可以从活动中使用他的通用 PostData 实用程序类。我认为他应该能够使用它。最后,它只是一个适合他的用例的实用程序类。
    • 同意,AsyncTask 本身可能需要一些修改或添加,但通用类是要走的路。我会编辑。
    • 巨大的优势(希望有一个)为编写一个整洁的助手类付出了额外的努力。这份工作太棒了,我只能挑剔 post_data / get_data 的名字;-)
    猜你喜欢
    • 2015-10-01
    • 1970-01-01
    • 2017-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    • 1970-01-01
    • 2011-07-24
    相关资源
    最近更新 更多