【问题标题】:Strange NPE behavior while working with ArrayLists使用 ArrayList 时出现奇怪的 NPE 行为
【发布时间】:2018-01-01 16:28:15
【问题描述】:

我在一个名为 GlobalDataHolder.java 的类上有 3 个名为 hp,att & def 的 public static ArrayList<Integer> 数组列表。当我尝试从另一个名为 MainScreenFragment.java 的类的名为 addSelectedCardToGlobalUserBox 的方法中将整数值添加到那些 ArrayLists 时,我得到一个 NPE 表明 hp @ 987654328@ 为空,因此阻止我向其添加值。奇怪的是,这个异常只发生在我在物理设备上而不是在模拟器上运行应用程序时。有什么想法吗?

数组列表:

    // Holds each card's hp stats
public static ArrayList<Integer> hp = new ArrayList<>();

// Holds each card's att stats
public static ArrayList<Integer> att = new ArrayList<>();

// Holds each card's def stats
public static ArrayList<Integer> def = new ArrayList<>();

addSelectedCardToGlobalUserBox() 方法:

    /**
 * Add the selected card's icon to the Global User Box
 * @param position Holds the selected card's position.
 * This is used to define where the icon should be placed in the grid &
 * which icon from the DataBase was selected
 */
private void addSelectedCardToGlobalUserBox(int position) {
    GlobalDataHolder.dataHolder.add(ImageAdapter.mThumbIds[position]);
    GlobalDataHolder.cardArts.add(CardInfoDatabase.cardArts[position]);
    GlobalDataHolder.cardNameAndDescription.add(CardInfoDatabase.cardNameAndDescription[position]);
    GlobalDataHolder.leaderSkills.add(CardInfoDatabase.leaderSkills[position]);
    GlobalDataHolder.superAttacksName.add(CardInfoDatabase.superAttacksName[position]);
    GlobalDataHolder.superAttacksDesc.add(CardInfoDatabase.superAttacksDesc[position]);
    GlobalDataHolder.passiveSkillsName.add(CardInfoDatabase.passiveSkillsName[position]);
    GlobalDataHolder.passiveSkillsDesc.add(CardInfoDatabase.passiveSkillsDesc[position]);
    GlobalDataHolder.hp.add(CardInfoDatabase.hp[position]);
    GlobalDataHolder.att.add(CardInfoDatabase.att[position]);
    GlobalDataHolder.def.add(CardInfoDatabase.def[position]);
}

MainScrenFragment.java 类供参考:

public class MainScreenFragment extends Fragment {

// Main Grid View
GridView gridView;

public MainScreenFragment() {
    // Required empty public constructor
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_main_screen, container, false);

    gridView = view.findViewById(R.id.gridViewLayout);
    gridView.setAdapter(new ImageAdapter(getContext())); // used to set the contents of the GridView-in this case images-
    registerForContextMenu(gridView);

    // When an item from the GridView gets clicked
    gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            // Create a new Intent...
            Intent intent = new Intent(getContext(),CardViewActivity.class);
            intent.putExtra("Card Index",position);
            intent.putExtra("GLB_CARD_INDEX", -1);
            intent.putExtra("SCREEN_WIDTH",1080);
            startActivity(intent);
        }
    });
    return view;
}

// Create a Context Menu when an item in the GridView is long-pressed
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.setHeaderTitle("Card Options");
    //AdapterView.AdapterContextMenuInfo cmi = (AdapterView.AdapterContextMenuInfo) menuInfo;
    menu.add(1,v.getId(),0, "Add Card to GLB");
    menu.add(2,v.getId(),0,"Add Card to JP");
}

// When an item in the context menu gets selected, call a method
@Override
public boolean onContextItemSelected(MenuItem item) {

    // Get some extra info about the contextMenu
    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

    int position = info.position; // clicked view's position

    if(item.getTitle().equals("Add Card to GLB")) {
        addCardMessage("Card added to GLB");
        addSelectedCardToGlobalUserBox(position);
    } else if (item.getTitle().equals("Add Card to JP")) {
        addCardMessage("Card added to JP");
        addSelectedCardToJPUserBox(position);
    } else
    {
        return false;
    }
    return false;
}

/**
 * Creates a snackbar message, telling the user which card was added to which box
 * @param text Defines into which User Box the card was added
 */
private void addCardMessage( String text) {
      final Snackbar snackbar = Snackbar.make(gridView, text ,Snackbar.LENGTH_LONG);

      snackbar.setAction("Dismiss", new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            snackbar.dismiss();
        }
    });
    snackbar.setActionTextColor(Color.MAGENTA);
    snackbar.show();
}

/**
 * Add the selected card's icon to the Global User Box
 * @param position Holds the selected card's position.
 * This is used to define where the icon should be placed in the grid &
 * which icon from the DataBase was selected
 */
private void addSelectedCardToGlobalUserBox(int position) {
    GlobalDataHolder.dataHolder.add(ImageAdapter.mThumbIds[position]);
    GlobalDataHolder.cardArts.add(CardInfoDatabase.cardArts[position]);
    GlobalDataHolder.cardNameAndDescription.add(CardInfoDatabase.cardNameAndDescription[position]);
    GlobalDataHolder.leaderSkills.add(CardInfoDatabase.leaderSkills[position]);
    GlobalDataHolder.superAttacksName.add(CardInfoDatabase.superAttacksName[position]);
    GlobalDataHolder.superAttacksDesc.add(CardInfoDatabase.superAttacksDesc[position]);
    GlobalDataHolder.passiveSkillsName.add(CardInfoDatabase.passiveSkillsName[position]);
    GlobalDataHolder.passiveSkillsDesc.add(CardInfoDatabase.passiveSkillsDesc[position]);
    GlobalDataHolder.hp.add(CardInfoDatabase.hp[position]);
    GlobalDataHolder.att.add(CardInfoDatabase.att[position]);
    GlobalDataHolder.def.add(CardInfoDatabase.def[position]);
}

/**
 * Add the selected card's icon to the JP User Box
 * @param position Holds the selected card's position.
 * This is used to define where the icon should be placed in the grid &
 * which icon from the DataBase was selected
 */
private void addSelectedCardToJPUserBox(int position) {
    JPDataHolder.dataHolder.add(ImageAdapter.mThumbIds[position]);
    JPDataHolder.cardArts.add(CardInfoDatabase.cardArts[position]);
    JPDataHolder.cardNameAndDescription.add(CardInfoDatabase.cardNameAndDescription[position]);
    JPDataHolder.leaderSkills.add(CardInfoDatabase.leaderSkills[position]);
    JPDataHolder.superAttacksName.add(CardInfoDatabase.superAttacksName[position]);
    JPDataHolder.superAttacksDesc.add(CardInfoDatabase.superAttacksDesc[position]);
    JPDataHolder.passiveSkillsName.add(CardInfoDatabase.passiveSkillsName[position]);
    JPDataHolder.passiveSkillsDesc.add(CardInfoDatabase.passiveSkillsDesc[position]);
    JPDataHolder.hp.add(CardInfoDatabase.hp[position]);
    JPDataHolder.att.add(CardInfoDatabase.att[position]);
    JPDataHolder.def.add(CardInfoDatabase.def[position]);
}

}

NPE:

01-01 16:05:51.421 22357-22357/com.dcv.spdesigns.dokkancards E/AndroidRuntime: 致命异常: main 进程:com.dcv.spdesigns.dokkancards,PID:22357 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“boolean java.util.ArrayList.add(java.lang.Object)” 在 com.dcv.spdesigns.dokkancards.ui.MainScreenFragment.addSelectedCardToGlobalUserBox(MainScreenFragment.java:122) 在 com.dcv.spdesigns.dokkancards.ui.MainScreenFragment.onContextItemSelected(MainScreenFragment.java:79) 在 android.support.v4.app.Fragment.performContextItemSelected(Fragment.java:2502) 在 android.support.v4.app.FragmentManagerImpl.dispatchContextItemSelected(FragmentManager.java:3319) 在 android.support.v4.app.FragmentController.dispatchContextItemSelected(FragmentController.java:357) 在 android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:377) 在 android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:195) 在 android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108) 在 android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108) 在 com.android.internal.policy.PhoneWindow$PhoneWindowMenuCallback.onMenuItemSelected(PhoneWindow.java:4020) 在 com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:761) 在 com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:157) 在 com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:904) 在 com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:894) 在 com.android.internal.view.menu.MenuPopup.onItemClick(MenuPopup.java:128) 在 android.widget.AdapterView.performItemClick(AdapterView.java:339) 在 android.widget.AbsListView.performItemClick(AbsListView.java:1718) 在 android.widget.AbsListView$PerformClick.run(AbsListView.java:4184) 在 android.widget.AbsListView$13.run(AbsListView.java:6754) 在 android.os.Handler.handleCallback(Handler.java:751) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6776) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

【问题讨论】:

    标签: java android android-studio arraylist integer


    【解决方案1】:

    您必须在代码中的某处分配这些变量null。尝试创建变量final 并检查null 的分配位置(编译失败将指示您分配null 的位置)。

    【讨论】:

      猜你喜欢
      • 2013-02-15
      • 1970-01-01
      • 2013-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-26
      相关资源
      最近更新 更多