繁体   English   中英

Android应用程序中的AsyncTask用于多个REST端点

[英]AsyncTask in android app for more than one REST endpoint

在Android中,有一种比使用带参数的单个AsyncTask更好的方法来确定要调用哪个REST端点?

我需要打电话:

 www.test.com/api/room/id    
 www.test.com/api/room/id/booking

AsyncTask是为单个doInBackground()方法设计的,它可以执行单个操作,例如调用:

www.test.com/api/room/id

我不想创建多个AsyncTasks实例,每个REST端点一个。

后端将使用:

RoomClient = new RoomClient();
roomClient.getID()
roomClient.getBookingForRoom()

在Android中,它看起来像我需要的

class RoomFromId extends AsyncTask
...
call www.test.com/api/room/id

class BookingForRoom extends AsyncTask
..
call www.test.com/api/room/id/booking

我在Android应用程序中理想的是,编写一个可以在后台调用所有REST端点的休眠客户端的习惯用法,而不必在自己的AsyncTask执行每个端点。 我更喜欢使用Android而不是第三方库。

创建一个从AsyncTask扩展的泛型类,它返回从YourBaseModel扩展的泛型类型的响应(我称之为M)

public class HttpRequest<M extends BaseModel> extends AsyncTask<Object, Integer, M> {
public enum RequestMethod {
    GET("GET"), POST("POST");

    private final String requestMethod;

    RequestMethod(String requestMethod) {
        this.requestMethod = requestMethod;
    }

    public String getValue() {
        return requestMethod;
    }
}

    private Context context = null;
    private String url;
    private OnResponseCallback onResponseCallback;
    private OnFailureCallback onFailureCallback;
    private RequestMethod method;
    private int statusCode;
    private String message;
    private Class<M> responseModel;
    private Object body = null;
    private String token;

    private HttpRequest() {

    }

    @Override
    protected M doInBackground(Object... voids) {
        try {
             HttpURLConnection connection = getHttpConnection();
             connection.connect();

            int statusCode = connection.getResponseCode();
            if (connection.getResponseCode() / 100 != 2) {
                this.statusCode = statusCode;
                this.message = connection.getResponseMessage();
                return JsonParser.getErrorBodyAs(responseModel, statusCode, 
message);
            }

            InputStreamReader streamReader = new
                    InputStreamReader(connection.getInputStream());

            return JsonParser.getErrorBodyAs(responseModel, statusCode, 
convertInputStreamToString(streamReader));

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private HttpURLConnection getHttpConnection() throws IOException {
        URL url = new URL(this.url);

        HttpURLConnection connection = (HttpURLConnection) 
 url.openConnection();
        connection.setRequestMethod(method.getValue());
        connection.setRequestProperty("Content-Type", "application/json");
        connection.setRequestProperty("Authorization", "Bearer " + token);
        connection.setReadTimeout(30000);
        connection.setConnectTimeout(30000);

    if (method == RequestMethod.POST) {
        connection.setDoInput(true);
        connection.setDoOutput(true);

        if (body != null) {
            OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
            writer.write(new Gson().toJson(body));
            writer.flush();
        }
    }

    return connection;
}

@Override
protected void onPostExecute(M m) {
    if (m == null) {
        if ((message != null && !message.equals("") && statusCode != 0)) {
            HttpException httpException = new HttpException(statusCode, message);
            onFailureCallback.onFailure(httpException);
        } else {
            onFailureCallback.onFailure("unknown error");
        }
    } else {
        onResponseCallback.onResponse(m);
    }
}

public static String convertInputStreamToString(InputStreamReader inputStreamReader) throws IOException {
    if (inputStreamReader == null) {
        return "";
    }

    BufferedReader reader = new BufferedReader(inputStreamReader);
    StringBuilder stringBuilder = new StringBuilder();

    String inputLine;
    String result;

    while ((inputLine = reader.readLine()) != null) {
        stringBuilder.append(inputLine);
    }

    reader.close();
    inputStreamReader.close();
    return stringBuilder.toString();
}

static public class Builder {
    HttpRequest t = new HttpRequest();

    public Builder setContext(Context context) {
        t.context = context;
        return this;
    }

    public Builder setUrl(String url) {
        t.url = url;
        return this;
    }

    public Builder setRequestMethod(RequestMethod method) {
        t.method = method;
        return this;
    }

    public Builder setBody(Object body) {
        t.body = body;
        return this;
    }

    public Builder setToken(String token) {
        t.token = token;
        return this;
    }

    public HttpRequest get() {
        return t;
    }

    public HttpRequest run(Class<?> responseTypeClass,
                           OnResponseCallback onResponseCallback,
                           OnFailureCallback onFailureCallback) {
        t.responseModel = responseTypeClass;
        t.onResponseCallback = onResponseCallback;
        t.onFailureCallback = onFailureCallback;
        t.execute();
        return t;
    }

    public Builder() {
    }
 }
}

你可以像这样使用它:

HttpRequest.Builder builder = new HttpRequest.Builder();
builder.setContext(context)
            .setRequestMethod(HttpRequest.RequestMethod.POST)
            .setBody(body)
            .setUrl("http://url")
            .run(YourResponeModel.class, new OnResponseCallback() {
                @Override
                public void onResponse(Object response) {
                },
               new OnFailureCallback() {
                    @Override
                    public void onFailure(Object throwable) {

                    }
            });

在您创建的扩展AsyncTask的类中,您可以创建构造函数并传递您想要/需要的任何内容。

在这种情况下,您可以定义一个扩展AsyncTask的类ApiManager,并传递一个定义要调用的方法的常量。 在该构造函数中,您可以将变量保存到ApiManager对象,然后在doInBackground方法中进行检查。

所以,要打电话给房间/身份证你可以这样做:

new ApiManager(ROOM_FROM_ID).execute(...

并打电话给房间/ id /预订:

new ApiManager(BOOKING_FOR_ROOM).execute(...

而ApiManager类应该是这样的:

class ApiManager extends AsyncTask... {
    private int method;
    public ApiManager(int method) {
        this.method = method;
    }
    ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM