2016-11-21 1 views
-1

는 Occasionaly 내 안드로이드 응용 프로그램에서 컨텍스트를

충돌 대신 PathClassLoader 원인이 철새 이동 경로의 WarningContextClassLoader를 받고, 내 DB 스키마를 업데이트 할 이동 경로를 사용합니다. 지금까지는 하나의 마이 그 레이션 만 있어도 3 개의 테이블이 생성되었습니다. 이동 경로에 대한 단순하고 평범한 사업. 그것은 매우 잘 작동합니다 ... 대부분의 시간! 때때로이 오류 (전체 스택 이하)와 충돌 :

java.lang.ClassCastException: android.app.LoadedApk$WarningContextClassLoader 
cannot be cast to dalvik.system.PathClassLoader 

내가 그 오류에 관한 몇 가지 질문이 있습니다

  • LoadedApk.WarningContextClassLoader 무엇

    ?
  • dalvik.system.PathClassLoader 대신 때때로 사용되는 이유는 무엇입니까?
  • 내 앱, Android 시스템 또는 이동 경로의 버그입니까?

나는 또한 내가 이동 경로 내에서 명시 적으로 클래스 로더를 삽입 할 수 것으로 나타났습니다 (Flyway.setClassLoader())

  • 나는 확실히 올바른 클래스 로더는 어떻게받을 수 있나요?

특정 활동의 컨텍스트가 아닌 이동 경로에 응용 프로그램 컨텍스트를 주입한다는 점에 유의하십시오.

버전

나는 org.flywaydb 사용 : 이동 경로 코어 : 4.0.2

나는 안드로이드 4.2.2 (젤리 빈, API 레벨 17) 및 4.4 (킷캣, API에서이 문제를 발견 레벨 19). AFAIK, 상위 버전에서는 절대로 발생하지 않았습니다.

스택 추적

Exception java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mycompany.myapp.free.debug/com.mycompany.MainActivity}: java.lang.ClassCastException: android.app.LoadedApk$WarningContextClassLoader cannot be cast to dalvik.system.PathClassLoader 
    android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2306) 
    android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2358) 
    android.app.ActivityThread.access$600 (ActivityThread.java:156) 
    android.app.ActivityThread$H.handleMessage (ActivityThread.java:1340) 
    android.os.Handler.dispatchMessage (Handler.java:99) 
    android.os.Looper.loop (Looper.java:153) 
    android.app.ActivityThread.main (ActivityThread.java:5299) 
    java.lang.reflect.Method.invokeNative (Method.java) 
    java.lang.reflect.Method.invoke (Method.java:511) 
    com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:833) 
    com.android.internal.os.ZygoteInit.main (ZygoteInit.java:600) 
    dalvik.system.NativeStart.main (NativeStart.java) 

Caused by java.lang.ClassCastException: android.app.LoadedApk$WarningContextClassLoader cannot be cast to dalvik.system.PathClassLoader 
    org.flywaydb.core.internal.util.scanner.classpath.android.AndroidScanner.<init> (AndroidScanner.java:46) 
    org.flywaydb.core.internal.util.scanner.Scanner.<init> (Scanner.java:38) 
    org.flywaydb.core.Flyway.execute (Flyway.java:1353) 
    org.flywaydb.core.Flyway.info (Flyway.java:1040) 
    com.mycompany.db.FlywayHelper.info (FlywayHelper.java:54) 
    com.mycompany.db.FlywayHelper.migrate (FlywayHelper.java:45) 
    com.mycompany.db.GW2DatabaseHelper.migrate (GW2DatabaseHelper.java:56) 
    com.mycompany.db.DbInit.initKeyGuild (DbInit.java:62) 
    com.mycompany.db.DbInit.init (DbInit.java:42) 
    com.mycompany.business.BootApp.boot (BootApp.java:79) 
    com.mycompany.MainActivity.onCreate (MainActivity.java:51) 
    android.app.Activity.performCreate (Activity.java:5122) 
    android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1081) 
    android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2270) 
    android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2358) 
    android.app.ActivityThread.access$600 (ActivityThread.java:156) 
    android.app.ActivityThread$H.handleMessage (ActivityThread.java:1340) 
    android.os.Handler.dispatchMessage (Handler.java:99) 
    android.os.Looper.loop (Looper.java:153) 
    android.app.ActivityThread.main (ActivityThread.java:5299) 
    java.lang.reflect.Method.invokeNative (Method.java) 
    java.lang.reflect.Method.invoke (Method.java:511) 
    com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:833) 
    com.android.internal.os.ZygoteInit.main (ZygoteInit.java:600) 
    dalvik.system.NativeStart.main (NativeStart.java) 

연구 갱신

의 목적은 나에게 분명하지 않지만, LoadedApk.WarningContextClassLoader가 유효한 클래스 로더로 표시하고 철새 이동 경로에 의해 지원 될 필요가 . pull request이 제출되었습니다.

private void injectClassLoader(Flyway flyway) { 
    ClassLoader classLoader = flyway.getClassLoader(); 
    if (classLoader != null && !(classLoader instanceof PathClassLoader)){ 
     flyway.setClassLoader(classLoader.getParent()); 
    } 
} 

답변

0

LoadedApk.WarningContextClassLoader 란 무엇입니까?

dalvik.system.PathClassLoader 대신 때때로 사용되는 이유는 무엇입니까?

이 특정 클래스 로더의 목적은 해당 패키지가 다른 패키지와 가상 컴퓨터를 공유 할 수 있음을 사용자에게 경고하는 것으로 보입니다.More info here, 덕분에 @orip.

내 앱, Android 시스템 또는 이동 경로의 버그입니까?

어쨌든 WarningContextClassLoader는 여전히 유효한 클래스 로더이므로 flyway에서 받아 들여야합니다. 안드로이드 스캐너로 제작 된 캐스트는 쓸모가 없었습니다.

솔루션

1

괜찮은 정보를 원하시면하여 commit message adding WarningContextClassLoader있다 : 사이에서

는 해결 방법은 예상되는 클래스 로더를 주입하기 위해 구현해야합니다. 나는 활동의 컨텍스트를 전달하는 것이 도움이 될 것 같아요.

+0

아니요. 나는 (flyway는 오픈 소스이다) 컨텍스트는 클래스 로더를 잡는 데 사용되지 않는다는 것을 확인했다. 사실 flyway는 classloader를 다음과 같이 초기화합니다. private private ClassLoader classLoader = Thread.currentThread(). getContextClassLoader();'공유에 감사드립니다! – Benoit

관련 문제