java - 从谷歌表格解析数据时应用程序崩溃
问题描述
I)下面是从谷歌表解析数据异步的代码,只要互联网速度良好但速度慢就会崩溃,它就可以正常工作。如何解决这个问题?我已经修复了没有互联网。
II)如果打开谷歌表进行更新(一次一行),系统在尝试打开时崩溃。如何跳过不可评估(或更新)的行?
III)有什么办法可以查出 google sheet 上次更新的时间吗?
IV)如何告诉谷歌地图在解析完成之前不要打开地图?
protected void ReadGoogleSheetAsync(){
new DownloadWebpageTask(new AsyncResult() {
@Override
public void onResult(JSONObject object) {
processJson(object);
}
}).execute("https://spreadsheets.google.com/tq?key=mykey");
}
private void processJson(JSONObject object) {
try {
JSONArray rows = object.getJSONArray("rows");
for (int r = 0; r < rows.length(); ++r) {
JSONObject row = rows.getJSONObject(r);
JSONArray columns = row.getJSONArray("c");
UserData ud = new UserData();
ud.setId(columns.getJSONObject(0).getString("f"));
ud.setName(columns.getJSONObject(1).getString("v"));
ud.setState(columns.getJSONObject(2).getString("v"));
}
catch (JSONException e) {
e.printStackTrace();
}
}
这是基于来自 git的DownloadWebpageTask.java 。
堆栈跟踪:
08/03 06:41:06: Launching 'MapsActivity' on vivo vivo 1902.
$ adb shell am start -n "com.example.fmtxstatus/com.example.fmtxstatus.MapsActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER Waiting for process to come online... Connected to process 6659 on device 'vivo-vivo_1902-CIEMU8KRPFLFHEBU'. Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page. D/VivoTheme: load old package name start I/mple.fmtxstatu: The ClassLoaderContext is a special shared library. W/mple.fmtxstatu: JIT profile information will not be recorded: profile file does not exits.
JIT profile information will not be recorded: profile file does not exits. D/NightModeController: com.example.fmtxstatus = true
disable nightmode package:com.example.fmtxstatus I/FtBuild: getRomVersion mRomVer=9.0 D/VivoPhoneWindow: DEBUG_ALIENSCREEN:getRotation mRotation=0 I/PhoneWindow: initSystemUIColor I/zzbz: Making Creator dynamically W/mple.fmtxstatu: Unsupported class loader W/mple.fmtxstatu: Skipping duplicate class check due to unsupported classloader I/DynamiteModule: Considering local module com.google.android.gms.maps_dynamite:0 and remote module com.google.android.gms.maps_dynamite:202614000 I/DynamiteModule: Selected remote version of com.google.android.gms.maps_dynamite, version >= 202614000 V/DynamiteModule: Dynamite loader version >= 2, using loadModule2NoCrashUtils I/DynamiteLoaderV2: [71] Mapsdynamite W/mple.fmtxstatu: Unsupported class loader W/mple.fmtxstatu: Skipping duplicate class check due to unsupported classloader I/Google Maps Android API: Google Play services client version: 12451000 I/Google Maps Android API: Google Play services package version: 202614029 W/mple.fmtxstatu: Accessing hidden field Ljava/nio/Buffer;->address:J (light greylist, reflection) I/mple.fmtxstatu: The ClassLoaderContext is a special shared library. E/libc: Access denied finding property "persist.vendor.log.tel_dbg" W/com.example.fmtxstatus: type=1400 audit(0.0:118917): avc: denied { read } for comm=4173796E635461736B202332 name="u:object_r:mtk_em_tel_log_prop:s0" dev="tmpfs" ino=6814 scontext=u:r:untrusted_app:s0:c252,c256,c512,c768 tcontext=u:object_r:mtk_em_tel_log_prop:s0 tclass=file permissive=0 D/NetworkSecurityConfig: No Network Security Config specified, using platform default D/OpenGLRenderer: Dumper init 4 threads <0x7a04d12b40> D/OpenGLRenderer: <com.example.fmtxstatus> is running.
Skia GL Pipeline I/SurfaceFactory: [static] sSurfaceFactory = com.mediatek.view.impl.SurfaceFactoryImpl@5b77117 D/ViewRootImpl[MapsActivity]: hardware acceleration = true , fakeHwAccelerated = false, sRendererDisabled = false, forceHwAccelerated = false, sSystemRendererDisabled = false V/PhoneWindow: DecorView setVisiblity: visibility = 0, Parent = android.view.ViewRootImpl@ff0122, this = DecorView@13807b3[MapsActivity] V/PhoneWindow: DecorView setVisiblity: visibility = 0, Parent = android.view.ViewRootImpl@ff0122, this = DecorView@13807b3[MapsActivity] I/CatcherGestureDetector: DecorView onAttached D/yuan: onVisibilityChanged----com.google.maps.api.android.lib6.impl.ci{2c1c49c G.ED..C.. ......I. 0,0-0,0} D/Surface: Surface::allocateBuffers(this=0x79f461d000) I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0 I/OpenGLRenderer: Initialized EGL, version 1.4 D/OpenGLRenderer: Swap behavior 2 D/Surface: Surface::connect(this=0x79f461d000,api=1) D/TextureView: getHardwareLayer, createNewSurface:true I/BufferQueue: [unnamed-6659-0](this:0x7a03285800,id:0,api:0,p:-1,c:-1) BufferQueue core=(6659:com.example.fmtxstatus) W/mple.fmtxstatus: type=1400 audit(0.0:118918): avc: denied { read } for name="u:object_r:graphics_debug_prop:s0" dev="tmpfs" ino=6754 scontext=u:r:untrusted_app:s0:c252,c256,c512,c768 tcontext=u:object_r:graphics_debug_prop:s0 tclass=file permissive=0 E/libc: Access denied finding property "vendor.debug.sf.stc_interval" W/mple.fmtxstatus: type=1400 audit(0.0:118919): avc: denied { read } for name="u:object_r:debug_bq_dump_prop:s0" dev="tmpfs" ino=6713 scontext=u:r:untrusted_app:s0:c252,c256,c512,c768 tcontext=u:object_r:debug_bq_dump_prop:s0 tclass=file permissive=0 E/libc: Access denied finding property "vendor.debug.bq.dump" W/System: ClassLoader referenced unknown path: system/framework/mediatek-cta.jar I/BufferQueueConsumer: [unnamed-6659-0](this:0x7a03285800,id:0,api:0,p:-1,c:6659) connect(C): consumer=(6659:com.example.fmtxstatus) controlledByApp=true E/libc: Access denied finding property "vendor.debug.bq.dump" W/mple.fmtxstatus: type=1400 audit(0.0:118920): avc: denied { read } for name="u:object_r:debug_bq_dump_prop:s0" dev="tmpfs" ino=6713 scontext=u:r:untrusted_app:s0:c252,c256,c512,c768 tcontext=u:object_r:debug_bq_dump_prop:s0 tclass=file permissive=0 I/BufferQueueConsumer: [unnamed-6659-0](this:0x7a03285800,id:0,api:0,p:-1,c:6659) setConsumerName: unnamed-6659-0 E/libc: Access denied finding property "vendor.debug.bq.line" W/mple.fmtxstatus: type=1400 audit(0.0:118921): avc: denied { read } for name="u:object_r:graphics_debug_prop:s0" dev="tmpfs" ino=6754 scontext=u:r:untrusted_app:s0:c252,c256,c512,c768 tcontext=u:object_r:graphics_debug_prop:s0 tclass=file permissive=0 E/libc: Access denied finding property "vendor.debug.bq.dump" I/BufferQueueConsumer: [SurfaceTexture-0-6659-0](this:0x7a03285800,id:0,api:0,p:-1,c:6659) setConsumerName: SurfaceTexture-0-6659-0 W/mple.fmtxstatus: type=1400 audit(0.0:118922): avc: denied { read } for name="u:object_r:debug_bq_dump_prop:s0" dev="tmpfs" ino=6713 scontext=u:r:untrusted_app:s0:c252,c256,c512,c768 tcontext=u:object_r:debug_bq_dump_prop:s0 tclass=file permissive=0 I/System.out: e:java.lang.ClassNotFoundException: com.mediatek.cta.CtaHttp I/BufferQueueConsumer: [SurfaceTexture-0-6659-0](this:0x7a03285800,id:0,api:0,p:-1,c:6659) setDefaultBufferSize: width=720 height=1404 D/OpenGLRenderer: 0x7a032fb740 setSurfaceTexture: 0x0 to 0x7a032d1800 D/Linux: [Posix_connect Debug]Process com.example.fmtxstatus :443 E/ion: ioctl c0044901 failed with code -1: Invalid argument I/GLConsumer: [SurfaceTexture-0-6659-0] attachToContext D/OpenSSLLib: OpensslErr:Module:12(177:); file:external/boringssl/src/crypto/asn1/asn1_lib.c ;Line:168;Function:ASN1_get_object D/OpenSSLLib: OpensslErr:Module:12(177:); file:external/boringssl/src/crypto/asn1/asn1_lib.c ;Line:168;Function:ASN1_get_object I/System.out: [OkHttp] sendRequest>> I/System.out: [OkHttp] sendRequest<< E/Google Maps Android API: Authorization failure. Please see https://developers.google.com/maps/documentation/android-api/start for how to correctly set up the map. E/Google Maps Android API: In the Google Developer Console (https://console.developers.google.com)
com.example.fmtxstatus W/System: ClassLoader referenced unknown path: system/framework/mediatek-cta.jar I/System.out: e:java.lang.ClassNotFoundException: com.mediatek.cta.CtaHttp D/Linux: [Posix_connect Debug]Process com.example.fmtxstatus :443 D/OpenSSLLib: OpensslErr:Module:12(177:); file:external/boringssl/src/crypto/asn1/asn1_lib.c ;Line:168;Function:ASN1_get_object D/OpenSSLLib: OpensslErr:Module:12(177:); file:external/boringssl/src/crypto/asn1/asn1_lib.c ;Line:168;Function:ASN1_get_object I/System.out: [OkHttp] sendRequest>> I/System.out: [OkHttp] sendRequest<< W/DynamiteModule: Local module descriptor class for com.google.android.gms.googlecertificates not found. I/DynamiteModule: Considering local module com.google.android.gms.googlecertificates:0 and remote module com.google.android.gms.googlecertificates:5
Selected remote version of com.google.android.gms.googlecertificates, version >= 5 I/DynamiteLoaderV2: [71] Googlecertificates W/mple.fmtxstatu: Unsupported class loader W/mple.fmtxstatu: Skipping duplicate class check due to unsupported classloader I/System.out: [OkHttp] sendRequest>> I/System.out: [OkHttp] sendRequest<< I/System.out: [OkHttp] sendRequest>> I/System.out: [OkHttp] sendRequest<< I/Choreographer: Skipped 52 frames! The application may be doing too much work on its main thread.
解决方案
该问题似乎与 HttpURLConnection 对象的处理不当有关。类 DownloadWebpageTask 中的 downloadUrl() 方法实现存在问题,可能与查询 1-3 相关,该变量responseCode
从未使用过。
如果响应不是HttpURLConnection.HTTP_OK
,请尝试重新连接(或直到自定义超时)或返回空字符串。在网速慢或连接不良时,响应不会是HttpURLConnection.HTTP_OK
,因此尝试引用 json-object 可能会导致未定义的行为。
private String downloadUrl(String urlString) throws IOException {
/*...*/
conn.connect();
responseCode = conn.getResponseCode();
if( responseCode == HttpURLConnection.HTTP_OK)
{
// do something
}
else
{
// retry or return null string
}
}
仅当 json-object 不为空时,才应调用片段中的函数 processJson(object)。这些修改应处理查询 1 到 3 下的问题。
protected void ReadGoogleSheetAsync(){
new DownloadWebpageTask(new AsyncResult() {
@Override
public void onResult(JSONObject object) {
if(object) processJson(object);
}
}).execute("https://spreadsheets.google.com/tq?key=mykey");
}
对于与 google maps api 相关的查询 4, OnMapReadyCallback
在地图准备好使用时调用。覆盖onMapReady()
方法以查找地图是否准备好。
推荐阅读
- ios - 在 Apple Store 上为公司分发 iOS 应用程序
- python - 从行中提取特定列并合并列
- corda - 使用 Corda OS RPC 客户端连接到 Corda Enterprise 节点
- php - 我有一个表图像和album_images。不需要album_images 表吗?
- css - 如何使用引导程序将 div 稍微放在图像上
- java - 如何使用 Java Optional 来防止读取未初始化的数组?
- symfony - 在更新另一个实体的同时创建一个实体
- c++ - C++ 重载 | 返回常量值的(按位或)运算符
- circleci-2.0 - circleci 过滤器分支不工作
- python - 让烧瓶应用程序中的两个页面使用相同的 html 是不好的做法吗?