我遇到了在正在更新的Android應用程序中調用URL.setURLStreamHandlerFactory(factory);
導致的意外錯誤。setURLStreamHandlerFactory和「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);
}
}
簡介:
這裏是我的情況:我保持企業的方式使用非市場應用。我的公司出售帶有由企業開發和維護的預安裝應用程序的平板電腦。這些預裝應用程序不是ROM的一部分;它們被安裝爲典型的未知來源應用程序。我們不會通過Play商店或任何其他市場執行更新。相反,應用程序更新由自定義更新管理器應用程序控制,該應用程序直接與我們的服務器通信以執行OTA更新。
問題:
這更新管理器應用程序,我維護,偶爾需要更新自己。在應用程序自身更新後,立即通過我在AndroidManifest中註冊的android.intent.action.PACKAGE_REPLACED
廣播重新開始。然而,在應用程序的重啓更新後,我偶爾收到這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)
注意,大部分時間,應用程序重新啓動正常。但是,每過一段時間,我都會遇到上述錯誤。我很困惑,因爲只有地方我打電話setURLStreamHandlerFactory
在這裏,它是在static
塊,我認爲 - 雖然糾正我,如果我錯了 - 只調用一次,當ApplicationRoot
類如果第一次加載。但是,它似乎被稱爲兩次,導致上述錯誤。
問:
什麼在熾熱的SAMS是怎麼回事?我在這一點上唯一的猜測是,對於更新應用VM /過程是一樣的以前安裝正在更新應用程序,所以,當爲新ApplicationRoot
的static
塊被調用時,URLStreamHandlerFactory
集由舊ApplicationRoot
仍然「活躍」。這可能嗎?我怎樣才能避免這種情況?看到它並不總是發生,似乎是某種競爭條件;也許在Android的APK安裝例程中?謝謝,
編輯:
附加代碼的要求。這裏是清單部分涉及廣播
<receiver android:name=".OnSelfUpdate" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
而且BroadcastReceiver
本身
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;
}
}
}
}
}
在一個正切的說明中,決定拋出'Error'而不是'IllegalStateException'的人需要被打耳光。 – chrylis
可以發佈用於發送廣播和清單屬性的代碼以捕獲它嗎? – Simas
@Simas Added。廣播由OS發送。 – pathfinderelite