任何人都有一个例子,你在哪里读过一个protobuf,使用凌空?我已经读过你可以实现ProtobufRequest类,但我找不到它的文档。谢谢你的帮助。
答案 0 :(得分:2)
我已经做到了,工作还可以,希望它是有帮助的。首先创建ProtobufRequest类,如下面扩展Request,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 {
}
答案 1 :(得分:1)
发件人: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);
}
}
答案 2 :(得分:-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);
如果您有解决方案,请不要忘记分享。
答案 3 :(得分:-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); } }