Wystąpił nieoczekiwany błąd spowodowany wywołaniem URL.setURLStreamHandlerFactory(factory);
w zaktualizowanej aplikacji systemu Android.setURLStreamHandlerFactory i "java.lang.Error: Factory already set"
public class ApplicationRoot extends Application {
static {
/* Add application support for custom URI protocols. */
final URLStreamHandlerFactory factory = new URLStreamHandlerFactory() {
@Override
public URLStreamHandler createURLStreamHandler(final String protocol) {
if (ExternalProtocol.PROTOCOL.equals(protocol)) {
return new ExternalProtocol();
}
if (ArchiveProtocol.PROTOCOL.equals(protocol)) {
return new ArchiveProtocol();
}
return null;
}
};
URL.setURLStreamHandlerFactory(factory);
}
}
Intro:
Oto moja sytuacja: Mam utrzymanie aplikacji non-rynkowych stosowanych w modzie przedsiębiorstw. Moja firma sprzedaje tablety z wstępnie zainstalowanymi aplikacjami opracowanymi i utrzymywanymi przez firmę. Te wstępnie zainstalowane aplikacje nie są częścią ROM; są instalowane jako typowe aplikacje Nieznane źródło. Nie wykonujemy aktualizacji za pośrednictwem Sklepu Play ani żadnego innego rynku. Zamiast tego aktualizacje aplikacji są kontrolowane przez niestandardową aplikację Update Manager, która komunikuje się bezpośrednio z naszymi serwerami w celu wykonywania aktualizacji OTA.
Problem:
Ten Aktualizacja aplikacji Menedżer, której mam utrzymania, od czasu do czasu musi się zaktualizować. Natychmiast po aktualizacji aplikacja restartuje się za pomocą transmisji android.intent.action.PACKAGE_REPLACED
, którą rejestruję w AndroidManifest. Jednak po ponownym uruchomieniu aplikacji natychmiast po aktualizacji, ja sporadycznie otrzymać ten Error
java.lang.Error: Factory already set
at java.net.URL.setURLStreamHandlerFactory(URL.java:112)
at com.xxx.xxx.ApplicationRoot.<clinit>(ApplicationRoot.java:37)
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1208)
at android.app.Instrumentation.newApplication(Instrumentation.java:996)
at android.app.Instrumentation.newApplication(Instrumentation.java:981)
at android.app.LoadedApk.makeApplication(LoadedApk.java:511)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2625)
at android.app.ActivityThread.access$1800(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1384)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5653)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at dalvik.system.NativeStart.main(Native Method)
Należy pamiętać, że większość czasu, aplikacja uruchomi się ponownie prawidłowo. Jednak co jakiś czas pojawia się powyższy błąd. Jestem zakłopotany, ponieważ tutaj znajduje się i jest to robione w bloku , który, jak sądzę, - chociaż poprawi mnie, jeśli się mylę - jest wywoływany tylko raz, gdy klasa ApplicationRoot
jest ładowana po raz pierwszy . Jednak wydaje się, że jest on nazywany dwukrotnie, powodując powyższy błąd.
Pytanie:
Co w płonących Sams się dzieje? My tylko domyślać, w tym momencie jest to, że VM/Sposób zaktualizowanej aplikacji jest taka sama jak wcześniej zainstalowany aplikację, która jest aktualizowana, więc gdy blok static
dla nowegoApplicationRoot
jest wywoływana, zestaw URLStreamHandlerFactory
przez staryApplicationRoot
jest nadal "aktywny". czy to możliwe? Jak mogę uniknąć tej sytuacji? Widząc, że nie zawsze tak się dzieje, wydaje się, że jest to jakiś rodzaj wyścigu; może w ramach procedury instalacji APK Androida? Dzięki,
Edit:
Kod dodatkowy żądanie.Oto manifest część czynienia z Broadcast
<receiver android:name=".OnSelfUpdate" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
A BroadcastReceiver
sama
public class OnSelfUpdate extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
/* Get the application(s) updated. */
final int uid = intent.getIntExtra(Intent.EXTRA_UID, 0);
final PackageManager packageManager = context.getPackageManager();
final String[] packages = packageManager.getPackagesForUid(uid);
if (packages != null) {
final String thisPackage = context.getPackageName();
for (final String pkg : packages) {
/* Check to see if this application was updated. */
if (pkg.equals(thisPackage)) {
final Intent intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
break;
}
}
}
}
}
W notatce stycznej, ktokolwiek zdecydował się rzucić "Błąd" zamiast "IllegalStateException", musi zostać spoliczkowany. – chrylis
Czy można wysłać kod wysyłania atrybutów emisji i manifestu w celu ich przechwycenia? – Simas
@Simas Dodano. Transmisja jest wysyłana przez system operacyjny. – pathfinderelite