2016-12-07 14 views
0

にキャストすることはできませんCHARここでは以下の例外のログです:は、ClassCastExceptionがスロー理由:[] android.app.SharedPreferencesImpl

java.lang.ClassCastException: char[] cannot be cast to android.app.SharedPreferencesImpl 
at android.app.ContextImpl.getSharedPreferences(ContextImpl.java:358) 
at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:171) 
at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:171) 
at com.android.internal.telephony.cat.CatService.saveCmdToPreference(CatService.java:2632) 
at com.android.internal.telephony.cat.CatService.handleDBHandler(CatService.java:2079) 
at com.android.internal.telephony.cat.CatService.handleMessage(CatService.java:1841) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Loo|debug info:dalvik.system.VMStack.getThreadStackTrace(Native Method)|java.lang.Thread.getStackTrace(Thread.java:580)|java.lang.Thread.getAllStackTraces(Thread.java:522)|com.letv.bsp.crashhandler.utils.LogUtils.trace(LogUtils.java:86)|com.letv.bsp.crashhandler.CrashHandleService.reportException(CrashHandleService.java:915)|com.letv.bsp.crashhandler.CrashHandleService.onStartCommand(CrashHandleService.java:663)|android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3291)|android.app.ActivityThread.-wrap18(ActivityThread.java)|android.app.ActivityThread$H.handleMessage(ActivityThread.java:1674)|android.os.Handler.dispatchMessage(Handler.java:111)|android.os.Looper.loop(Looper.java:207)|android.app.ActivityThread.main(ActivityThread.java:5905)|java.lang.reflect.Method.invoke(Native Method)|com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)|com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)|, blk: false printBlacklist the current black list : 

そして、ここでは、以下の例外がスローされますandroid.app.ContextImpl.getSharedPreferencesにコードされています

@Override 
public SharedPreferences getSharedPreferences(String name, int mode) { 
    SharedPreferencesImpl sp; 
    synchronized (ContextImpl.class) { 
     if (sSharedPrefs == null) { 
      sSharedPrefs = new ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>>(); 
     } 

     final String packageName = getPackageName(); 
     ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName); 
     if (packagePrefs == null) { 
      packagePrefs = new ArrayMap<String, SharedPreferencesImpl>(); 
      sSharedPrefs.put(packageName, packagePrefs); 
     } 

     // At least one application in the world actually passes in a null 
     // name. This happened to work because when we generated the file name 
     // we would stringify it to "null.xml". Nice. 
     if (mPackageInfo.getApplicationInfo().targetSdkVersion < 
       Build.VERSION_CODES.KITKAT) { 
      if (name == null) { 
       name = "null"; 
      } // here is the line 358 
     } 

     sp = packagePrefs.get(name); 
     if (sp == null) { 
      File prefsFile = getSharedPrefsFile(name); 
      sp = new SharedPreferencesImpl(prefsFile, mode); 
      packagePrefs.put(name, sp); 
      return sp; 
     } 
    } 
    if ((mode & Context.MODE_MULTI_PROCESS) != 0 || 
     getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) { 
     // If somebody else (some other process) changed the prefs 
     // file behind our back, we reload it. This has been the 
     // historical (if undocumented) behavior. 
     sp.startReloadIfChangedUnexpectedly(); 
    } 
    return sp; 
} 

ログ情報が正しいと仮定し、ほぼ正しいはずです。

私の最初の質問は、ContextImpl.javaファイルの358行でキャスト例外をスローするとはどういう意味ですか?そこには正しいブレースしかありません。 spはSharedPreferencesImplとして宣言され、それがキャスト操作が必要ですので、私はライン358以下の文を推測

は例外

sp = packagePrefs.get(name); 

のルートケースの場合にgetメソッドの戻り値と割り当て、値があればreturnがchar []である場合、キャスト例外はスローする必要があります。この説明は非常に合理的です。 SharedPreferencesImplは、一度そのため

packagePrefs = new ArrayMap<String, SharedPreferencesImpl>(); 

で宣言としてではなく、packagePrefsの値をパラメータ化している、それがpackagePrefsへのchar []の値の型を置くためにチャンスを持っていないはずです。次に、私はもう一度混乱しています。コードはどこにこの例外があり、なぜ発生しますか?

他の同様の問題があり、ログは次のとおりです。

java.lang.ClassCastException: char[] cannot be cast to    com.android.internal.util.StateMachine$LogRec 
at com.android.internal.util.StateMachine$LogRecords.add(StateMachine.java:665) 
at com.android.internal.util.StateMachine$SmHandler.performTransitions(StateMachine.java:830) 
at com.android.internal.util.StateMachine$SmHandler.handleMessage(StateMachine.java:801) 
at android.os.Handler.dispatchMessage(Handler.java:111) 
at android.os.Looper.loop(Looper.java:207) 
at android.os.HandlerThread.run(HandlerThread.java:61) 

とそれに対応するコードcom.android.internal.util.StateMachine.LogRecordsである:それは両方ともに思える

 private Vector<LogRec> mLogRecVector = new Vector<LogRec>(); 
     synchronized void add(StateMachine sm, Message msg, String messageInfo, IState state, 
      IState orgState, IState transToState) { 
     mCount += 1; 
     if (mLogRecVector.size() < mMaxSize) { 
      mLogRecVector.add(new LogRec(sm, msg, messageInfo, state, orgState, transToState)); 
     } else { 
      LogRec pmi = mLogRecVector.get(mOldestIndex); 
      mOldestIndex += 1; 
      if (mOldestIndex >= mMaxSize) { 
       mOldestIndex = 0; 
      } 
      pmi.update(sm, msg, messageInfo, state, orgState, transToState); 
     } 
    } 

ジェネリックについての問題である。ここでは専門家の助けを借りて、ありがとうございます。

+0

'getSharedPreferences(String name、int mode)'メソッドはどのパッケージとクラスですか?その名前のスタックトレース内には、異なるパッケージを持つ2つのメソッドがあります。あなたは絶対に***あなたは私たちに正しい方法を示していることを確認していますか? –

+0

このメソッドはandroid.app.ContextImplクラスにあります。更新しました。そして、スタックトレース内にその名前で2つのメソッドがあり、それぞれ異なるパッケージがあることをどうやって知ることができますか?あなたは私のことを明確に説明できますか?おそらくルートケースが他のパッケージで間違ったクラスを使用している可能性があります。 – Saint

+0

他のコードパスが 'char []'オブジェクトをこれらのデータ構造体に挿入する可能性があると思われる理由はありますか?(例えば、他の場所で 'char []'オブジェクトを使用して、 – dimo414

答えて

0

最初の問題(行番号はエラーに対応していません)では、前回のコンパイル以降に3行(おそらくname = "null"の条件付き)が追加されました。あなたのソースとバイナリが同期していないという強いヒントです。

あなたのコードスニペットをコンパイルした場合packagePrefsmLogRecVectorは一般的なものですので、我々はClassCastExceptionを見るべきではない第二の問題については、私はこれは不可能だ同意するだろうが(sSharedPrefs生タイプだった場合は、問題に遭遇するかもしれませんが、Iそうでないと仮定して)私の最初の理論は、スタック・トレースがソース・コードと一線を画していないというヒントを再構築する必要があるということです。

完全な再構築がうまくいかない場合、これはAndroid固有の問題(おそらくProGuardを使用しているのでしょうか?)と考える必要があります。 OracleJDKまたはOpenJDKでこれを複製できますか? MCVEを作成して問題を再現できる場合は、問題の最下部まで手伝ってください。

+0

最初の問題は正しいです、私はテスターが提供するバージョンコードから日付情報の意味を誤解しています。行358は、sp = packagePrefs.get(name);を指します。ソースコードがバイナリと一貫した後そして、このメソッドは作成されて以来変更されていません。 この問題はユーザーの携帯電話で発生するため、気軽に起こり、複製できません。 – Saint

+0

私はそれが複製できない場合どのくらいの助けができるか分かりません。自分の携帯電話に奇妙なことがありますか? Androidの古いバージョンを実行していますか? – dimo414

関連する問題