Android 间歇性错误 onitemclick java.lang.IndexOutOfBoundsException: 索引 0 无效,大小为 0
Android intermittent error onitemclick java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
无法弄清楚这一点,我已经搜索了很多。无法在我的任何测试设备上模拟错误,但偶尔会发生在我的一些用户身上。
我有一个自定义列表视图适配器,从在线数据库中提取了 6 个项目并添加到列表中。我还在列表底部添加了一个额外的静态页脚。
我知道发生此错误时列表视图中没有任何内容,它是 0,因此应用程序无法获取位置 - 由于从在线数据库中提取字符串。
我试图通过 if/else 来解决这个问题,但仍然出现 indexoutofbounds 错误。在线:
if(mCategoryAdapter.getItem(position)!=null)
或
Category category = mCategoryAdapter.getItem(position);
我的问题是 - 我假设用户在列表完全填充之前点击列表?有什么想法可以阻止它吗?
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//assigning XML view
setContentView(R.layout.activity_category);
//fill the list view from data from parse.com using custom CategoryAdapter
mCategoryAdapter = new CategoryAdapter(this, new ArrayList<Category>());
//assigning ListView to XML ListView
mListView = (ListView)findViewById(R.id.category_list);
mListView.setAdapter(mCategoryAdapter);
customExercisesView = getLayoutInflater().inflate(R.layout.category_custom_exercises_row_item,mListView,false);
//make items in list clickable
mListView.setOnItemClickListener(this);
//parse query to retrieve the categories
getCategoryList();
}
public void getCategoryList()
{
//parse query to pull all the current available exercises from the db
ParseQuery<Category> query = ParseQuery.getQuery(Category.class).fromLocalDatastore();
//call to parse.com to start the query
query.findInBackground(new FindCallback<Category>() {
@Override
public void done(List<Category> categories, ParseException error) {
if(categories !=null)
{
//add all the categories into the list
mCategoryAdapter.addAll(categories);
//add the custom exercises footer after we have added the rest
mListView.addFooterView(customExercisesView);
//sort the list alphabetically
mCategoryAdapter.sort(new Comparator<Category>() {
@Override
public int compare(Category category, Category t1) {
return category.getName().compareTo(t1.getName());
}
});
}
}
});
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//to make phone vibrate for 20 milliseconds when clicking an item in the list
Vibrator v = (Vibrator) this.getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(20);
//users are selecting one of the 6 main exercise categories
if(position<=5) {
if(mCategoryAdapter.getItem(position)!=null) {
//giving the listed exercises in the list view the ability to be clicked on
Category category = mCategoryAdapter.getItem(position);
//Get category ID and name to pass to Exercise List
mCategoryID = category.getObjectId();
mCategoryName = category.getName();
Intent exercise_intent = new Intent(this, ExerciseList.class);
exercise_intent.putExtra("categoryID", mCategoryID);
exercise_intent.putExtra("categoryName", mCategoryName);
startActivity(exercise_intent);
}
else
Toast.makeText(this, "Categories are still loading, please try again", Toast.LENGTH_SHORT).show();
}else
{
//user is selecting custom exercises
Intent custom_exercise_intent = new Intent(this, CustomExerciseList.class);
startActivity(custom_exercise_intent);
}
Exception java.lang.IndexOutOfBoundsException: Invalid index 0,
size is 0 java.util.ArrayList.throwIndexOutOfBoundsException
(ArrayList.java:255) java.util.ArrayList.get (ArrayList.java:308)
android.widget.ArrayAdapter.getItem (ArrayAdapter.java:337)
adam.exercisedictionary.CategoryList.onItemClick (CategoryList.java:139) android.widget.AdapterView.performItemClick
(AdapterView.java:308) android.widget.AbsListView.performItemClick
(AbsListView.java:1154) android.widget.AbsListView$PerformClick.run
(AbsListView.java:3074) android.widget.AbsListView.run
(AbsListView.java:3905) android.os.Handler.handleCallback
(Handler.java:739) android.os.Handler.dispatchMessage
(Handler.java:95) android.os.Looper.loop (Looper.java:135)
android.app.ActivityThread.main (ActivityThread.java:5595)
java.lang.reflect.Method.invoke (Method.java)
java.lang.reflect.Method.invoke (Method.java:372)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run
(ZygoteInit.java:960) com.android.internal.os.ZygoteInit.main
(ZygoteInit.java:755)
您是否检查过您的 6 项数据集是否为空或在该代码点不可用?首先,检查并访问数据集中的单个项目。
不知道行不行。试试看。 DB 可能会 return 空列表。
mCategoryAdapter = new CategoryAdapter(this, new ArrayList<Category>());
在这一行中,您传递的 ArrayList
没有任何值,这意味着它的大小是 zero
。这里你必须通过 ArrayList
已经填充了一些 items.Like:
List<Category> list = new ArrayList<Category>();
list.add(category1);
list.add(category2);
list.add(category3);
mCategoryAdapter = new CategoryAdapter(this, list);
非常感谢你们,
我明白了。我确定在用户单击并启动 onclick 方法时列表视图已填充。
我意识到我的查询是从本地数据存储中检索的,我在启动应用程序时加载了类别,同时显示启动画面。问题是如果这些类别在启动时没有加载,那么此查询将无法从本地数据存储中检索任何内容。
解决方案是通过重新尝试从 Internet 检索值来处理本地数据存储区查询是否为空,并且已经解决了问题,此后没有崩溃。
一旦用户连接到网络并下载了类别,他们就不必再次连接,因为它们已永久固定在设备上。
public void getCategoryList()
{
//parse query to pull all the current available exercises from the db
ParseQuery<Category> query = ParseQuery.getQuery(Category.class).fromLocalDatastore();
//call to parse.com to start the query
query.findInBackground(new FindCallback<Category>() {
@Override
public void done(List<Category> categories, ParseException error) {
if(categories !=null)
{
mCategoryAdapter.clear();
//add all the categories into the list
mCategoryAdapter.addAll(categories);
}
else
{
//check we have internet
if(DetectConnection.isConnected(getApplicationContext())) {
//backup get categories from net
getCategoryListFromParse();
}
else
{
//no internet and issues getting categories, let user know
Toast.makeText(getApplicationContext(),"Please check your internet connection", Toast.LENGTH_SHORT).show();
}
}
}
});
}
public void getCategoryListFromParse()
{
//parse query to pull all the current available exercises from the db
ParseQuery<Category> query = ParseQuery.getQuery(Category.class);
//call to parse.com to start the query
query.findInBackground(new FindCallback<Category>() {
@Override
public void done(List<Category> categories, ParseException error) {
if(categories !=null)
{
Category.pinAllInBackground(categories);
//add all the categories into the list
mCategoryAdapter.addAll(categories);
}
}
});
}
无法弄清楚这一点,我已经搜索了很多。无法在我的任何测试设备上模拟错误,但偶尔会发生在我的一些用户身上。
我有一个自定义列表视图适配器,从在线数据库中提取了 6 个项目并添加到列表中。我还在列表底部添加了一个额外的静态页脚。
我知道发生此错误时列表视图中没有任何内容,它是 0,因此应用程序无法获取位置 - 由于从在线数据库中提取字符串。
我试图通过 if/else 来解决这个问题,但仍然出现 indexoutofbounds 错误。在线:
if(mCategoryAdapter.getItem(position)!=null)
或
Category category = mCategoryAdapter.getItem(position);
我的问题是 - 我假设用户在列表完全填充之前点击列表?有什么想法可以阻止它吗?
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//assigning XML view
setContentView(R.layout.activity_category);
//fill the list view from data from parse.com using custom CategoryAdapter
mCategoryAdapter = new CategoryAdapter(this, new ArrayList<Category>());
//assigning ListView to XML ListView
mListView = (ListView)findViewById(R.id.category_list);
mListView.setAdapter(mCategoryAdapter);
customExercisesView = getLayoutInflater().inflate(R.layout.category_custom_exercises_row_item,mListView,false);
//make items in list clickable
mListView.setOnItemClickListener(this);
//parse query to retrieve the categories
getCategoryList();
}
public void getCategoryList()
{
//parse query to pull all the current available exercises from the db
ParseQuery<Category> query = ParseQuery.getQuery(Category.class).fromLocalDatastore();
//call to parse.com to start the query
query.findInBackground(new FindCallback<Category>() {
@Override
public void done(List<Category> categories, ParseException error) {
if(categories !=null)
{
//add all the categories into the list
mCategoryAdapter.addAll(categories);
//add the custom exercises footer after we have added the rest
mListView.addFooterView(customExercisesView);
//sort the list alphabetically
mCategoryAdapter.sort(new Comparator<Category>() {
@Override
public int compare(Category category, Category t1) {
return category.getName().compareTo(t1.getName());
}
});
}
}
});
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//to make phone vibrate for 20 milliseconds when clicking an item in the list
Vibrator v = (Vibrator) this.getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(20);
//users are selecting one of the 6 main exercise categories
if(position<=5) {
if(mCategoryAdapter.getItem(position)!=null) {
//giving the listed exercises in the list view the ability to be clicked on
Category category = mCategoryAdapter.getItem(position);
//Get category ID and name to pass to Exercise List
mCategoryID = category.getObjectId();
mCategoryName = category.getName();
Intent exercise_intent = new Intent(this, ExerciseList.class);
exercise_intent.putExtra("categoryID", mCategoryID);
exercise_intent.putExtra("categoryName", mCategoryName);
startActivity(exercise_intent);
}
else
Toast.makeText(this, "Categories are still loading, please try again", Toast.LENGTH_SHORT).show();
}else
{
//user is selecting custom exercises
Intent custom_exercise_intent = new Intent(this, CustomExerciseList.class);
startActivity(custom_exercise_intent);
}
Exception java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0 java.util.ArrayList.throwIndexOutOfBoundsException (ArrayList.java:255) java.util.ArrayList.get (ArrayList.java:308) android.widget.ArrayAdapter.getItem (ArrayAdapter.java:337) adam.exercisedictionary.CategoryList.onItemClick (CategoryList.java:139) android.widget.AdapterView.performItemClick (AdapterView.java:308) android.widget.AbsListView.performItemClick (AbsListView.java:1154) android.widget.AbsListView$PerformClick.run (AbsListView.java:3074) android.widget.AbsListView.run (AbsListView.java:3905) android.os.Handler.handleCallback (Handler.java:739) android.os.Handler.dispatchMessage (Handler.java:95) android.os.Looper.loop (Looper.java:135) android.app.ActivityThread.main (ActivityThread.java:5595) java.lang.reflect.Method.invoke (Method.java) java.lang.reflect.Method.invoke (Method.java:372) com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:960) com.android.internal.os.ZygoteInit.main (ZygoteInit.java:755)
您是否检查过您的 6 项数据集是否为空或在该代码点不可用?首先,检查并访问数据集中的单个项目。
不知道行不行。试试看。 DB 可能会 return 空列表。
mCategoryAdapter = new CategoryAdapter(this, new ArrayList<Category>());
在这一行中,您传递的 ArrayList
没有任何值,这意味着它的大小是 zero
。这里你必须通过 ArrayList
已经填充了一些 items.Like:
List<Category> list = new ArrayList<Category>();
list.add(category1);
list.add(category2);
list.add(category3);
mCategoryAdapter = new CategoryAdapter(this, list);
非常感谢你们,
我明白了。我确定在用户单击并启动 onclick 方法时列表视图已填充。
我意识到我的查询是从本地数据存储中检索的,我在启动应用程序时加载了类别,同时显示启动画面。问题是如果这些类别在启动时没有加载,那么此查询将无法从本地数据存储中检索任何内容。
解决方案是通过重新尝试从 Internet 检索值来处理本地数据存储区查询是否为空,并且已经解决了问题,此后没有崩溃。
一旦用户连接到网络并下载了类别,他们就不必再次连接,因为它们已永久固定在设备上。
public void getCategoryList()
{
//parse query to pull all the current available exercises from the db
ParseQuery<Category> query = ParseQuery.getQuery(Category.class).fromLocalDatastore();
//call to parse.com to start the query
query.findInBackground(new FindCallback<Category>() {
@Override
public void done(List<Category> categories, ParseException error) {
if(categories !=null)
{
mCategoryAdapter.clear();
//add all the categories into the list
mCategoryAdapter.addAll(categories);
}
else
{
//check we have internet
if(DetectConnection.isConnected(getApplicationContext())) {
//backup get categories from net
getCategoryListFromParse();
}
else
{
//no internet and issues getting categories, let user know
Toast.makeText(getApplicationContext(),"Please check your internet connection", Toast.LENGTH_SHORT).show();
}
}
}
});
}
public void getCategoryListFromParse()
{
//parse query to pull all the current available exercises from the db
ParseQuery<Category> query = ParseQuery.getQuery(Category.class);
//call to parse.com to start the query
query.findInBackground(new FindCallback<Category>() {
@Override
public void done(List<Category> categories, ParseException error) {
if(categories !=null)
{
Category.pinAllInBackground(categories);
//add all the categories into the list
mCategoryAdapter.addAll(categories);
}
}
});
}