1

任何人都有一个例子,你在其中使用 volley 阅读 protobuf?我读过你可以实现 ProtobufRequest 类,但我找不到它的文档。谢谢您的帮助。

4

4 回答 4

2

我已经完成了,工作还可以,希望对您有所帮助。首先创建如下扩展 Request 的 ProtobufRequest 类,Request 是 Volley 中的基本请求类,然后​​,您可以创建自定义请求扩展 ProtobufRequest 进行自定义 doParse( ). 仅作为参考。

RequestData 是 SomeProto 消息,

private static final int SOCKET_TIMEOUT = 30000;

/** Content type for request. */
private static final String PROTOCOL_CONTENT_TYPE = "application/x-protobuf";

private static final Object sDecodeLock = new Object();

private RequestData mRequestData;
private BaseCallback mCallback;

public ProtobufRequest(RequestData data, BaseCallback callback) {
    super(Method.POST, Constants.SERVER_URL, callback);
    // TODO Auto-generated constructor stub
    mRequestData = data;
    mCallback = callback;
    this.setRetryPolicy(getRetryPolicy());
}

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    Map<String, String> headers = new HashMap<String, String>();
    headers.put("Charset", "UTF-8");
    headers.put("Content-Type", "application/x-protobuf");
    headers.put("Accept", "application/x-protobuf");

    return headers;
}

@Override
public String getBodyContentType() {
    return PROTOCOL_CONTENT_TYPE;
}

@Override
public RetryPolicy getRetryPolicy() {
    RetryPolicy retryPolicy = new DefaultRetryPolicy(SOCKET_TIMEOUT,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
    return retryPolicy;
}

    /**
    ** write the protobuf data to http request,it is very important
    */
@Override
public byte[] getBody() throws AuthFailureError {
    if (mRequestData == null) {
        return super.getBody();
    } else {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {

            baos.write(mRequestData.toByteArray());
        } catch (IOException e) {
            return super.getBody();
        }

        return baos.toByteArray();
    }
}

@Override
protected void deliverResponse(Object arg0) {
    mCallback.onResponse(arg0);
}

    /**
    ** parse the response result
    */
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
    synchronized (sDecodeLock) {
        try {
            return doParse(response, HttpHeaderParser.parseCacheHeaders(response));
        } catch (OutOfMemoryError e) {
            return Response.error(new ParseError(e));
        }
    }
}

abstract protected Response<T> doParse(NetworkResponse response, Entry entry)


public interface BaseCallback extends Listener<Object>, ErrorListener {

}
于 2014-02-25T07:03:55.920 回答
2

来自:cmcneil添加代码以防链接失效。Volley 或 Protocol Buffers 最终应该会有一个正式的实现,所以请在必要时更新它。

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.Listener;
import com.android.volley.RetryPolicy;
import com.android.volley.toolbox.HttpHeaderParser;
import com.google.protobuf.MessageLite;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by carson@convox.org on 5/10/15.
 */
 public class ProtoBufRequest<ReqT extends MessageLite, RespT extends MessageLite> extends Request<RespT> {

    private ReqT request;
    private final Class<RespT> responseType;
    private final Listener<RespT> listener;
    private static final String PROTOCOL_CONTENT_TYPE = "application/x-protobuf";
    private static final int SOCKET_TIMEOUT = 30000;

    public ProtoBufRequest(int method, String url, ReqT data, Class<RespT> responseType,
                           Listener<RespT> listener, Response.ErrorListener errorListener) {
        super(method, url, errorListener);
        this.listener = listener;
        this.request = data;
        this.responseType = responseType;
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Charset", "UTF-8");
        headers.put("Content-Type", PROTOCOL_CONTENT_TYPE);
        headers.put("Accept", PROTOCOL_CONTENT_TYPE);

        return headers;
    }

    @Override
    public byte[] getBody() throws AuthFailureError {
        if (request == null) {
            return super.getBody();
        }
        return request.toByteArray();
    }


    @Override
    protected Response<RespT> parseNetworkResponse(NetworkResponse response) {
        try {
            if (responseType == null) {
                throw new IllegalArgumentException("The response type was never provided.");
            }
                RespT responseInstance = responseType.newInstance();
                return (Response<RespT>) Response.success(
                        responseInstance.newBuilderForType().mergeFrom(response.data).build(),
                        HttpHeaderParser.parseCacheHeaders(response));
        } catch (Exception e) {
            e.printStackTrace();
            return Response.error(new ParseError(e));
        }
    }

    @Override
    public String getBodyContentType() {
        return PROTOCOL_CONTENT_TYPE;
    }

    @Override
    public RetryPolicy getRetryPolicy() {
        RetryPolicy retryPolicy = new DefaultRetryPolicy(SOCKET_TIMEOUT,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
        return retryPolicy;
    }

    @Override
    protected void deliverResponse(RespT response) {
        listener.onResponse(response);
    }
}
于 2016-08-02T14:49:18.940 回答
-1

这不是一个例子,我自己(还没有)做过,但我会这样做:

一种方法是扩展 JsonObjectRequest 并将每个协议缓冲区序列化和反序列化为 Json,使用:

 Message someProto = SomeProto.getDefaultInstance();
 String jsonFormat = JsonFormat.printToString(someProto);

Message.Builder builder = SomeProto.newBuilder();
String jsonFormat = _load json document from a source_;
JsonFormat.merge(jsonFormat, builder);

请参阅:https ://code.google.com/p/protobuf-java-format/

否则,如果您想将协议缓冲区序列化发送到 byte[],您可以扩展Request<T>. public byte[] getBody()您将为请求正文/有效负载覆盖,并Response<Message> parseNetworkResponse(NetworkResponse response)为答案提供保护。

然后,您将使用以下函数来序列化协议缓冲区。

byte[] toByteArray();

parseFrom(byte[] data);

如果您有解决方案,请不要忘记分享。

于 2013-12-13T12:11:29.067 回答
-1

只是把它贴在这里以防它有用:我搜索了很多通用方法来做类似于jeff wang的答案的事情。我找不到任何东西,所以我写了这个。让我知道您是否有任何方法可以摆脱那里未经检查的演员...

ProtobufRequest.java

public class ProtoBufRequest<ReqT extends Message, RespT extends Message> extends Request<RespT> {

  private ReqT request;
  private final Class<RespT> responseType;
  private final Listener<RespT> listener;
  private static final String PROTOCOL_CONTENT_TYPE = "application/x-protobuf";
  private static final int SOCKET_TIMEOUT = 30000;

  public ProtoBufRequest(int method, String url, ReqT data, Class<RespT> responseType,
                         Listener<RespT> listener, Response.ErrorListener errorListener) {
      super(method, url, errorListener);
      this.listener = listener;
      this.request = data;
      this.responseType = responseType;
  }

  @Override
  public Map<String, String> getHeaders() throws AuthFailureError {
      Map<String, String> headers = new HashMap<String, String>();
      headers.put("Charset", "UTF-8");
      headers.put("Content-Type", PROTOCOL_CONTENT_TYPE);
      headers.put("Accept", PROTOCOL_CONTENT_TYPE);

      return headers;
  }

  @Override
  public byte[] getBody() throws AuthFailureError {
      if (request == null) {
          return super.getBody();
      }
      return request.toByteArray();
  }


  @Override
  protected Response<RespT> parseNetworkResponse(NetworkResponse response) {
      try {
          if (responseType == null) {
              throw new IllegalArgumentException("The response type was never provided.");
          }
              RespT responseInstance = responseType.newInstance();
              return (Response<RespT>) Response.success(
                    responseInstance.newBuilderForType().mergeFrom(response.data).build(),
                      HttpHeaderParser.parseCacheHeaders(response));
      } catch (Exception e) {
          e.printStackTrace();
          return Response.error(new ParseError(e));
      }
  }

  @Override
  public String getBodyContentType() {
      return PROTOCOL_CONTENT_TYPE;
  }

  @Override
  public RetryPolicy getRetryPolicy() {
      RetryPolicy retryPolicy = new DefaultRetryPolicy(SOCKET_TIMEOUT,
              DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
      return retryPolicy;
  }

  @Override
  protected void deliverResponse(RespT response) {
      listener.onResponse(response);
  } 
}
于 2015-05-12T03:08:23.650 回答