1

私はアプリを開発していますが、エラーの原因を理解したり見つけたりするのに非常に大きな問題があります。完全なコードは Github で入手できます: https://github.com/lordgreg/Sfen。問題のある行は、常に 608 行付近の startActivity(intent) です ( https://github.com/lordgreg/Sfen/blob/master/app/src/main/java/gpapez/sfen/BackgroundService.java )

エラーを再現する方法は次のとおりです。

  • 新しいショートカット(ウィジェット)を作成する「アクション」を持つことができる新しいプロファイルを作成します-実際にはインテントをGson文字列として保存します(Uriのために(デ)シリアル化を使用する必要がありました)。
  • このプロファイルを何度でも実行できます (クリックするとすべてのアクションが実行されます)。インテントは問題なく実行されます。
  • 現在、特別な条件でトリガーされ、特定のプロファイルを実行する以外は何もしない「イベント」があります(プロファイルを再度クリックするのと同じです)。これは機能します。イベントの条件が満たされ、ブロードキャストEVENT_ENABLEDを送信し、受信者がそれを取得し、プロファイルをトリガーする機能を開始し、アクションを実行し、sendActivityがGsonから取得した意図で機能します。パーフェクトだ。
  • アプリを閉じて再度開くと、問題が発生します。
  • 次に、レシーバーがイベントを再実行するためのシグナルを送信します(これは、クリックすると機能し、プロファイルを手動でクリックすると機能します)。

エラーの一例を次に示します。

08-04 21:27:50.065  21621-21621/gpapez.sfen E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: gpapez.sfen, PID: 21621
    java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.wifi.STATE_CHANGE flg=0x4000010 (has extras) } in gpapez.sfen.Receiver@44b7a678
            at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:791)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:212)
            at android.app.ActivityThread.main(ActivityThread.java:5151)
            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:878)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
            at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.IllegalArgumentException
            at android.os.Parcel.nativeAppendFrom(Native Method)
            at android.os.Parcel.appendFrom(Parcel.java:436)
            at android.os.Bundle.writeToParcel(Bundle.java:1679)
            at android.os.Parcel.writeBundle(Parcel.java:641)
            at android.content.Intent.writeToParcel(Intent.java:7026)
            at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2084)
            at android.app.Instrumentation.execStartActivity(Instrumentation.java:1419)
            at android.app.ContextImpl.startActivity(ContextImpl.java:1079)
            at android.app.ContextImpl.startActivity(ContextImpl.java:1061)
            at android.content.ContextWrapper.startActivity(ContextWrapper.java:311)
            at gpapez.sfen.BackgroundService.runProfileActions(BackgroundService.java:647)
            at gpapez.sfen.BackgroundService.runEventActions(BackgroundService.java:749)
            at gpapez.sfen.BackgroundService.EventFinder(BackgroundService.java:346)
            at gpapez.sfen.Receiver.onReceive(Receiver.java:189)
            at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:781)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:212)
            at android.app.ActivityThread.main(ActivityThread.java:5151)
            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:878)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
            at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
            at dalvik.system.NativeStart.main(Native Method)

または別の:

08-04 21:38:30.950  22971-22971/gpapez.sfen E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: gpapez.sfen, PID: 22971
    java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.wifi.STATE_CHANGE flg=0x4000010 (has extras) } in gpapez.sfen.Receiver@451087f0
            at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:791)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:212)
            at android.app.ActivityThread.main(ActivityThread.java:5151)
            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:878)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
            at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.IllegalArgumentException
            at android.os.Parcel.nativeAppendFrom(Native Method)
            at android.os.Parcel.appendFrom(Parcel.java:436)
            at android.os.Bundle.writeToParcel(Bundle.java:1679)
            at android.os.Parcel.writeBundle(Parcel.java:641)
            at android.content.Intent.writeToParcel(Intent.java:7026)
            at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2084)
            at android.app.Instrumentation.execStartActivity(Instrumentation.java:1419)
            at android.app.ContextImpl.startActivity(ContextImpl.java:1079)
            at android.app.ContextImpl.startActivity(ContextImpl.java:1061)
            at android.content.ContextWrapper.startActivity(ContextWrapper.java:311)
            at gpapez.sfen.BackgroundService.runProfileActions(BackgroundService.java:647)
            at gpapez.sfen.BackgroundService.runEventActions(BackgroundService.java:749)
            at gpapez.sfen.BackgroundService.EventFinder(BackgroundService.java:346)
            at gpapez.sfen.Receiver.onReceive(Receiver.java:189)
            at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:781)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:212)
            at android.app.ActivityThread.main(ActivityThread.java:5151)
            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:878)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
            at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
            at dalvik.system.NativeStart.main(Native Method)

これが発生すると、アプリが使用できなくなります。システム設定に移動して、アプリ自体のデータを消去する必要があります。その後、再実行してプロファイルを再度作成し、プロファイルを表示するイベントを作成して、このコードを実行するだけのショートカット アクションをトリガーできます。

            /**
             * get Intent from saved setting
             *
             * http://stackoverflow.com/questions/22533432/create-object-from-gson-string-doesnt-work
             */
            class UriDeserializer implements JsonDeserializer<Uri> {
                @Override
                public Uri deserialize(final JsonElement src, final Type srcType,
                                       final JsonDeserializationContext context) throws JsonParseException {
                    return Uri.parse(src.getAsString());
                }
            }

            Gson gsonIntent = new GsonBuilder()
                    .registerTypeAdapter(Uri.class, new UriDeserializer())
                    .create();

            Intent intent = gsonIntent.fromJson(act.getSetting("shortcut_intent"), Intent.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            System.out.println("*** Opening intent\n" + act.getSetting("shortcut_intent"));

            startActivity(intent);

エラーが表示される行

 at gpapez.sfen.BackgroundService.runProfileActions(BackgroundService.java:647)

正確には:

startActivity(intent);

その後、アプリを再度開こうとすると、常に上記の例外が発生します。ここにひねりがあります...クラッシュ後しばらく待つと(+ 1分)、問題なくアプリが再開され、次のクラッシュまですべてを開き続けることができます。

なぜこれが起こっているのか助けてください...ミステリーを見つけて解決する人に喜んで支払います(両方とも行のstartActivity(intent)につながる不正な引数例外とブロードキャストインテントの受信エラー)!私を助けてくれたことに感謝の気持ちを表すことができるのはそれだけです!

ありがとうございました!

4

1 に答える 1

0

最終的にクラッシュの理由を見つけることができたので、私は自分の質問に答えます。

  1. 説明したように、プロファイル アクションを保存するとき、私たちの場合は Shortcut で、Shortcut Intent を保存する必要がありました。Gson は Uri (java.lang.RuntimeException: Failed to invoke private android.net.Uri() with no args) について不平を言ったので、独自の Serializer クラスと Deserializer クラスを作成し、それらを Gson オブジェクトに渡す必要があります。

その後、最終的に Gson を使用して Intent オブジェクトを String に保存できます。次のようになります。

{
    "mAction": "android.intent.action.VIEW",
    "mData": "http://www.amazon.com/",
    "mExtras": {
        "mParcelledData": {
            "mOwnsNativeParcelObject": true,
            "mNativePtr": -1197637952
        },
        "mHasFds": false,
        "mFdsKnown": true,
        "mAllowFds": true
    },
    "mFlags": 0
}

文字列に変換されたインテントが必要になったら、次のように呼び出します。

Intent intent = new Gson().fromJson(act.getSetting(MY_INTENT_STRING, Intent.class);

これにより問題が発生しなかったため、インテントが作成され、すべてが予想よりも優れていましたが、2 日間ブレークポイントを設定し、コードを 1 行ずつチェックした後、取得した実際の fromGson() 文字列を次に示します。

{
    "mAction": "android.intent.action.VIEW",
    "mData": "http://www.amazon.com/",
    "mExtras": {
        "mMap": {
            "com.android.browser.application_id": "-2531992419148236456"
        },
        "mHasFds": false,
        "mFdsKnown": true,
        "mAllowFds": true
    },
    "mFlags": 0
}

ご覧のとおり、Serializer と Deserializer を実装しても、いくつかの違いが生じます。

提案?

意図を保存するために GSON を使用しないでください。意図に関係なく、文字列に保存して、次のようにうまく受け取ることができます。

// like this to save intent
String mySavedIntent = intent.toUri(Intent.URI_INTENT_SCHEME)

// like this to retrieve intent from string
intent = Intent.parseUri(mySavedIntent, Intent.URI_INTENT_SCHEME)
于 2014-08-05T06:17:04.643 に答える