我的应用程序需要下载并解析一个大型JSON文件。 为了避免任何与内存相关的问题,我在1000个json对象的批量中从自定义转换器中的响应对象解析输入流。
一切正常,直到我想将解析后的对象返回给调用者的可观察对象。
我的API方法如下所示:
Observable<MyResponseStream> typesObs = api.getTypes(request.method, request.options);
响应由自定义转换器处理
public class MyResponseConverterFactory extends Converter.Factory {
public MyResponseConverterFactory() {
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
if (MyResponseStream.class.equals(type)) {
// We will process only response where the client wait for I2ctResponseStream
return MyResponseConverter.INSTANCE;
}
return null;
}
public static MyResponseConverterFactory create() {
return new MyResponseConverterFactory();
}
final static class MyResponseConverter implements Converter<ResponseBody, MyResponseStream> {
static final MyResponseConverter INSTANCE = new MyResponseConverter();
@Override
public MyResponseStream convert(ResponseBody responseBody) throws IOException {
return new MyResponseStream(responseBody.byteStream());
}
}
}
MyResponseStream
看起来像
public class MyResponseStream extends MyResponse<ArrayList<JSONObject>> {
private final static int BATCH_SIZE = 1000;
public interface ObjectsStreamListener {
void onObjectsParsed(String parentKey, ArrayList<ObjectNode> items);
}
private ArrayList<ObjectNode> mItems;
private ObjectMapper mMapper;
private ObjectsStreamListener mListener;
private InputStream mInputStream;
public MyResponseStream(InputStream inputStream) {
super();
mInputStream = inputStream;
mItems = new ArrayList<>();
}
public void start(ObjectsStreamListener listener) {
mListener = listener;
if (mInputStream != null) {
parse();
}
}
private void parse() {
try {
mMapper = new ObjectMapper();
JsonParser parser = mMapper.getFactory().createParser(mInputStream);
String key;
JsonToken currentToken = parser.nextToken();
while (currentToken != null) {
parser.nextFieldName();
key = parser.getCurrentName();
if ("method".equals(key)) {
method = parser.nextTextValue();
} else if ("success".equals(key)) {
isSuccess = parser.nextIntValue(0) == 1;
Cs.e("isSuccess " + isSuccess);
} else if ("data".equals(key)) {
currentToken = parser.nextToken();
parseData(parser);
} else {
currentToken = parser.nextToken();
}
}
parser.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void parseData(JsonParser parser) throws IOException {
String currentKey;
ObjectNode node;
while (parser.nextToken() != null) {
// Consume FIELD_NAME token
parser.nextFieldName();
// Get parent key (ex groups)
currentKey = parser.getCurrentName();
while (parser.getCurrentToken() == JsonToken.START_ARRAY) {
while (parser.nextToken() == JsonToken.START_OBJECT) {
node = mMapper.readTree(parser);
mItems.add(node);
if (mItems.size() == BATCH_SIZE) {
if (mListener != null) {
mListener.onObjectsParsed(currentKey, mItems);
mItems.clear();
}
}
}
}
if (!mItems.isEmpty()) {
if (mListener != null) {
mListener.onObjectsParsed(currentKey, mItems);
mItems.clear();
}
}
}
}
}
为了获取已解析的对象,我正在注册一个监听器
typesObs.map(responseStream -> {
responseStream.start(new MyResponseStream.ObjectsStreamListener() {
@Override public void onObjectsParsed(String parentKey, ArrayList<ObjectNode> items) {
Cs.e("parentKey " + parentKey + " items " + items);
}
});
return responseStream;
})
这种方法很有效,但它看起来不是一个好的解决方案,因为我没有以任何方式利用RxJava observable。
我的问题:有没有办法从转换器调用结果可观察onNext()
?
我想替换
mListener.onObjectsParsed(currentKey, mItems);
类似
retrofit.getRxCallAdapterFactory().getCallerObservable().onNext(items)
答案 0 :(得分:1)
您可以采取的一种方法是创建适配器而不是转换器。
这种方法可以按以下顺序运作:
`static Scanner scan;
public static void main(String[] args) {
scan = new Scanner(System.in);
double a = Math.pow(getHeight(), 2);
System.out.println(a);
double b = Math.pow(getWidth(), 2);
double c = a + b;
System.out.println(Math.sqrt(c));
scan.close();
}`
Observable<MyResponseStream>
检索retrofit.callAdapter(...)
Observable<Response>
。