android 上从 Double 到 Integer 的奇怪 ClassCastException

Strange ClassCastException from Double to Integer on android

我构建了一个 android 小部件,并在 WidgetService class 中扩展了 BroadcastReceiver。

发生了一件奇怪的事情,当我试图从 ArrayList 中获取一个整数时,它抛出了一个异常

public class WidgetService extends BroadcastReceiver {
      int currentIndex = -1;
      ArrayList<Integer> indexHitTimes = null;
      ArrayList<Integer> staredIndex = null;
      HashMap<Integer, Integer> staredIndexHitTimes = null;
      ...
      public void onReceive(Context context, Intent intent) {
            ...
            updateCurrentIndex();
            ...
      }
      private void updateCurrentIndex(){
            ...
            Random r = new Random();
            int size = staredIndex.size();
            int randomIndex = r.nextInt(size);
            currentIndex = staredIndex.get(randomIndex);    ->problem here
            currentIndexHitTimes = staredIndexHitTimes.get(currentIndex);
            minHitTimes = Collections.min(staredIndexHitTimes.values());
            ...
      }
}

虽然我检查了它是否是由 NullPointer 引起的,但没有线索。

是我的 jdk(1.8 版。0_74)还是 android 工作室的问题?(1.51 版) AndroidSDK版本:6.0(但我试过4.4,还是一样)

我尝试开始一个新项目并复制到它,但仍然无法正常工作。

怎么可能? 由于 "staredIndex" 是一个带有 Integer 参数的 ArrayList 并且 randomIndex 是一个 int,currentIndex 是并且 int.

"Double"来自哪里?

如何解决?

错误信息

java.lang.RuntimeException: Unable to start receiver 
heart.david.jp50_reviewer.WidgetService: java.lang.ClassCastException: 
java.lang.Double cannot be cast to java.lang.Integer
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2602)
at android.app.ActivityThread.access00(ActivityThread.java:147)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1358)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5253)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
at heart.david.jp50_reviewer.WidgetService.updateCurrentIndex(WidgetService.java:136)
at heart.david.jp50_reviewer.WidgetService.onReceive(WidgetService.java:51)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2595)
at android.app.ActivityThread.access00(ActivityThread.java:147) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1358) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:135) 
at android.app.ActivityThread.main(ActivityThread.java:5253) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 

Thanks everyone. The problem I found is here. The code below initialize the ArrayList.

        ...
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
        String json = sharedPreferences.getString("staredIndex", null);
        if(json == null){
            staredIndex = new ArrayList<Integer>();
            for(int i=0;i<hashMap_Characters.size();i++){
                boolean stared = hashMap_Stared.get(i);
                if(stared){
                    staredIndex.add(i);
                }
            }
            SharedPreferences.Editor editor = sharedPreferences.edit();
            Gson gson = new Gson();
            String staredIndex_json = gson.toJson(staredIndex);
            editor.putString("staredIndex", staredIndex_json);
            editor.commit();
        }else{
            Gson gson = new Gson();
            staredIndex = gson.fromJson(json, ArrayList.class); -> here! the staredIndex filled with Doubles!
        }
        ...

Then I change to this, and the problem is completely solved.

        ...
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
        String json = sharedPreferences.getString("indexHitTimes", null);
        if(json == null){
            indexHitTimes = new ArrayList<Integer>();
            for(int i=0;i<hashMap_Characters.size();i++){
                indexHitTimes.add(0);
            }
            SharedPreferences.Editor editor = sharedPreferences.edit();
            Gson gson = new Gson();
            Type type = new TypeToken<ArrayList<Integer>>(){}.getType();
            String indexHitTimes_json = gson.toJson(indexHitTimes, type);
            editor.putString("indexHitTimes", indexHitTimes_json);
            editor.commit();
        }else{
            Gson gson = new Gson();
            indexHitTimes = (ArrayList<Integer>)gson.fromJson(json, new TypeToken<ArrayList<Integer>>(){}.getType());
        }
        ...

使用

Double d = staredIndex.get(randomIndex);
currentIndex = d.intValue();

或者

currentIndex = (int) staredIndex.get(randomIndex);

如果您想从 double 转换为 int

问题来了,因为 ArrayList staredIndex 包含不同类型的 data.ArrayList 包含 Double 和 Integer 类型的数据,但是您已将 staredIndex ArrayList 声明为 Integer.You 应该只在 ArrayList 中添加整数类型数据或者你应该从 Double 到 Integer 进行类型转换。