我通常这样启动模拟器:
firebase emulators:start --import=test/local-dev --export-on-exit=test/local-dev
目的:将之前导出的数据导入到 local-dev 文件夹中,并在模拟器退出时保存所有数据。
重新启动我的开发计算机 (macOS Catalina) 后,我无法再使用 local-dev 文件夹中的数据,因为模拟器无法通过以下控制台输出启动:
firestore: Fatal error occurred:
Firestore Emulator has exited with code: 1,
stopping all running emulators
Run Code Online (Sandbox Code Playgroud)
firestore-debug.log 的内容:
Exception in thread "main" com.google.cloud.datastore.core.exception.DatastoreException: Failed to parse overall export metadata file
at com.google.cloud.datastore.emulator.impl.ExportImportUtil.parseOverallMetadataFile(ExportImportUtil.java:229)
at com.google.cloud.datastore.emulator.impl.ExportImportUtil.fetchEntities(ExportImportUtil.java:56)
at com.google.cloud.datastore.emulator.firestore.CloudFirestore.main(CloudFirestore.java:89)
Caused by: java.io.FileNotFoundException: ~/project-root/test/local-dev/firestore_export/firestore_export.overall_export_metadata (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at com.google.cloud.datastore.emulator.impl.ExportImportUtil.parseOverallMetadataFile(ExportImportUtil.java:219)
... 2 more
Run Code Online (Sandbox Code Playgroud)
我注意到firestore_export通常位于 local-dev 中的子文件夹丢失了:
$ ls test/local-dev/
firebase-export-metadata.json
Run Code Online (Sandbox Code Playgroud)
系统关闭过程似乎以某种方式损坏了导出文件夹。有什么想法如何/为什么吗?
使用Retrofit,在分页REST响应中加载"更多"数据的最佳方法是什么?
我正在从AsyncTasks + Loaders迁移到Retrofit.与此相关SO问题中的OP情况不同,我希望仅在请求时获取Retrofit获取数据,而不是一次性下载所有项目.目前,当用户通过调用滚动到当前列表视图页面的末尾时,可以很容易地执行此操作LoaderManager.restartLoader().
我们的客户使用的API的示例响应:
{
"data": [
{
"nid": 4382,
"comment_text": "some user comment", ...
}, ...
],
"paging": {
"nextPage": "http://api.domain.net/v2/comments?page=1&pageSize=20&requestLandmark=M4ewMnwxDUsdadf0NTIwfDU2OA==%3D%3D",
"itemsTotal": 5164,
"page": 0,
"pagerMax": 218,
"requestLandmark": "M4ewMnwxDUsdadf0NTIwfDU2OA=="
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我们可以像这样向我们的APIService提供'page'参数:
public interface APIService {
@GET("/comments/{page}") //
List<Comment> getComments(@Path("page") int page);
}
Run Code Online (Sandbox Code Playgroud)
然而,挑战在于我们还有许多其他端点,除了评论(用户故事,喜欢,趋势等)之外,还为我们提供了不同的数据列表,我们不想loadMore()为每个端点编写一个方法来获取其他页面因为如果有更好的选择.换句话说,为我们拥有的每个 GET请求/服务维护一个currentPageIndex是笨拙的,因为它会破坏托管列表视图的Fragment.该LoaderManager结构对我们来说工作得很好,因为我们创建了一个包装类,它只是简单地接受相应列表视图的回调,因此无论数据模型类型如何,我们都有一个点来管理分页.也就是说,我们的Fragment的recyclelerview onScroll监听器看起来像这样:
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
...
mLoadHandler.handleNewItemLoading(firstVisibleItem, visibleItemCount, totalItemCount);
...
}
Run Code Online (Sandbox Code Playgroud)
和mLoaderHandler是一个实例:
/**
* Handles new content …Run Code Online (Sandbox Code Playgroud) 我正在使用带有默认 Gson 解析器的 Retrofit 进行 JSON 处理。通常,我有一系列 4~5 个相关但略有不同的对象,它们都是公共基础的所有子类型(我们称之为“BaseType”)。我知道我们可以通过检查“类型”字段将不同的 JSON 反序列化为它们各自的子模型。最常用的方法是扩展 JsonDeserializer 并将其注册为 Gson 实例中的类型适配器:
class BaseTypeDeserializer implements JsonDeserializer<BaseType> {
private static final String TYPE_FIELD = "type";
@Override
public BaseType deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json.isJsonObject() && json.getAsJsonObject().has(TYPE_FIELD)) {
JsonObject jsonObject = json.getAsJsonObject();
final String type = jsonObject.get(TYPE_FIELD).getAsString();
if ("type_a".equals(type)) {
return context.deserialize(json, AType.class);
} else if ("type_b".equals(type)) {
return context.deserialize(json, BType.class);
} ...
// If you need to deserialize as BaseType,
// deserialize without …Run Code Online (Sandbox Code Playgroud) 我正在努力理解和/或让 Kotlin 泛型和多态性为我工作。考虑这段代码:
class Item<T: BaseAttributes> {
var id: Long = -1L
lateinit var type: String
lateinit var attributes: T
}
open class BaseAttributes {
lateinit var createdAt: String
lateinit var updatedAt: String
}
open class BaseResponseList<T : BaseAttributes> {
lateinit var items: List<Item<T>> // the collection of items fetched from an API
}
class FruitAttributes(val id: Long, val color: String /* ... */) : BaseAttributes()
class FruitResponseList: BaseResponseList<FruitAttributes>()
// base service for all types of items
interface ApiService { …Run Code Online (Sandbox Code Playgroud) 有谁知道如何从看起来像 "01:20" -> 1:20AM 和 "21:20" -> 9:20PM 的字符串中解析时间(小时、分钟和 AM/PM)?大多数解决方案似乎都假设或需要 Date 或 Calendar 对象。
我的输入时间实际上来自 TimePickerDialog(特别是这个 MaterialDateTimePicker 实现,所以我只收到小时、分钟和秒(整数)。
我希望能够以友好的方式格式化用户选择的时间,即 12:30PM、02:15AM 等。
我正在尝试使用 Joda 时间:
fun formattedTime(timeStr: String): String {
// Get time from date
val timeFormatter = DateTimeFormat.forPattern("h:mm a")
val displayTime = timeFormatter.parseLocalTime(timeStr)
return displayTime.toString()
}
Run Code Online (Sandbox Code Playgroud)
但是我在输入字符串(例如“1:20”)时收到此错误:
java.lang.IllegalArgumentException: Invalid format: "1:20" is too short
我也研究过SimpleDateFormat但它似乎需要一个完整的日期时间字符串,例如在这个相关问题中
android ×3
retrofit ×3
java ×2
generics ×1
gson ×1
jodatime ×1
kotlin ×1
pagination ×1
polymorphism ×1